Coder Social home page Coder Social logo

alamofirenetworkactivityindicator's Introduction

AlamofireNetworkActivityIndicator

Build Status CocoaPods Compatible Carthage Compatible Platform Twitter

Controls the visibility of the network activity indicator on iOS using Alamofire.

Features

  • Automatic Management of Activity Indicator Visibility
  • Delay Timers to Mitigate Flicker
  • Can Support URLSession Instances Not Managed by Alamofire
  • Comprehensive Test Coverage
  • Complete Documentation

Requirements

  • iOS 10.0+
  • Xcode 11+
  • Swift 5.1+

Dependencies

Communication

  • If you need help, use Stack Overflow. (Tag 'alamofire')
  • If you'd like to ask a general question, use Stack Overflow.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Alamofire into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'AlamofireNetworkActivityIndicator', '~> 3.1'

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate Alamofire into your Xcode project using Carthage, specify it in your Cartfile:

github "Alamofire/AlamofireNetworkActivityIndicator" ~> 3.1

Swift Package Manager (requires Xcode 11)

  1. Select File > Swift Packages > Add Package Dependency. Enter https://github.com/Alamofire/AlamofireNetworkActivityIndicator in the "Choose Package Repository" dialog.
  2. In the next page, specify the version resolving rule as "Up to Next Major" with "3.1.0" as its earliest version.
  3. After Xcode checking out the source and resolving the version, you can choose the "AlamofireNetworkActivityIndicator" library and add it to your app target.

Manually

If you prefer not to use either of the aforementioned dependency managers, you can integrate AlamofireNetworkActivityIndicator into your project manually.

Embedded Framework

  • Open up Terminal, cd into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:
$ git init
  • Add AlamofireNetworkActivityIndicator as a git submodule by running the following command:
$ git submodule add https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git
  • Open the new AlamofireNetworkActivityIndicator folder, and drag the AlamofireNetworkActivityIndicator.xcodeproj into the Project Navigator of your application's Xcode project.

    It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.

  • Select the AlamofireNetworkActivityIndicator.xcodeproj in the Project Navigator and verify the deployment target matches that of your application target.

  • Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.

  • In the tab bar at the top of that window, open the "General" panel.

  • Click on the + button under the "Embedded Binaries" section.

  • You will see two different AlamofireNetworkActivityIndicator.xcodeproj folders each with two different versions of the AlamofireNetworkActivityIndicator.framework nested inside a Products folder.

    It does not matter which Products folder you choose from.

  • Select the AlamofireNetworkActivityIndicator.framework and add it to your project.

  • And that's it!

    The AlamofireNetworkActivityIndicator.framework is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.


Usage

The NetworkActivityIndicatorManager manages the state of the network activity indicator. To begin using it, all that is required is to enable the shared instance in application:didFinishLaunchingWithOptions: in your AppDelegate.

NetworkActivityIndicatorManager.shared.isEnabled = true

By enabling the shared manager for the system, the network activity indicator will show and hide automatically as Alamofire requests start and complete.

Notifications

The NetworkActivityIndicatorManager manages the currently active network request count by observing notifications emitted from Alamofire. By observing the task state changes, the shared manager always knows how many requests are currently active and updates the visibility of the activity indicator accordingly.

It is possible to have the shared manager observe URLSession instances not inside Alamofire. You will need to emit matching notifications from the URLSessionDelegate matching those found in Alamofire.

Delay Timers

In order to make the activity indicator experience for a user as pleasant as possible, there need to be start and stop delays added in to avoid flickering. There are two such delay timers built into the shared manager.

Start Delay

The start delay is a time interval indicating the minimum duration of networking activity that should occur before the activity indicator is displayed. This helps avoid needlessly displaying the indicator for really fast network requests. The default value is 1.0 second. You can easily change the default value if needed.

NetworkActivityIndicatorManager.shared.startDelay = 1.0

Completion Delay

The completion delay is a time interval indicating the duration of time that no networking activity should be observed before dismissing the activity indicator. This allows the activity indicator to be continuously displayed between multiple network requests. Without this delay, the activity indicator tends to flicker. The default value is 0.2 seconds. You can easily change the default value if needed.

NetworkActivityIndicatorManager.shared.completionDelay = 0.2

FAQ

Why is this not in Alamofire?

In order to allow Alamofire to continue to be used in App Extensions, this logic could not be included in the Alamofire framework. In order to submit an App Extension to the App Store, it can only be linked against frameworks that specify they only use App Extension safe APIs. Since we want users to be able to use Alamofire in App Extensions, we MUST set the Require Only App Extension Safe APIs to true. Because of this, we cannot call non-safe App Extension APIs in the Alamofire framework. Controlling the activity indicator on iOS is done through non-safe App Extension APIs. Because of this, a separate library needed to be created.

But what about availability you say? Doesn't help in this case because availability checks still compile all the code. We could not use #if os(iOS) either because you cannot compile out logic specifically for iOS, but not for an iOS App Extension.


Credits

Alamofire is owned and maintained by the Alamofire Software Foundation. You can follow them on Twitter at @AlamofireSF for project updates and releases.

Donations

The ASF is looking to raise money to officially stay registered as a federal non-profit organization. Registering will allow us members to gain some legal protections and also allow us to put donations to use, tax free. Donating to the ASF will enable us to:

  • Pay our yearly legal fees to keep the non-profit in good status
  • Pay for our mail servers to help us stay on top of all questions and security issues
  • Potentially fund test servers to make it easier for us to test the edge cases
  • Potentially fund developers to work on one of our projects full-time

The community adoption of the ASF libraries has been amazing. We are greatly humbled by your enthusiasm around the projects, and want to continue to do everything we can to move the needle forward. With your continued support, the ASF will be able to improve its reach and also provide better legal safety for the core members. If you use any of our libraries for work, see if your employers would be interested in donating. Any amount you can donate today to help us reach our goal would be greatly appreciated.

paypal

License

AlamofireNetworkActivityIndicator is released under the MIT license. See LICENSE for details.

alamofirenetworkactivityindicator's People

Contributors

alphatroya avatar cicerocamargo avatar cnoon avatar erulezz avatar jshier avatar lutzifer avatar mrtnrst avatar naohta avatar readmecritic avatar rzulkoski avatar sinoru avatar xgopox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alamofirenetworkactivityindicator's Issues

network indicator disappear during upload

Hi, so during an upload of multipartformdata, the NetworkActivityIndicator disappear, usually between 7 to 15% of the upload completion.
Is there a way to fix this?
I use the version 2.2.0 of the framework which is installed with cocoapods.
Swift 3.1 with xcode 8.3.3

Swift3 Alamofire pod dependence XCode8 beta 6

Please update .podspecs for swift3 branch as I am having problems using the Podfile:

pod 'Alamofire',                            :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'swift3'
pod 'AlamofireNetworkActivityIndicator',    :git => 'https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git', :branch => 'swift3'

Updating pods with CocoaPods 1.1.0.beta.1 returns the next error:

  • Alamofire (= 4.0.0-beta.1) required by AlamofireNetworkActivityIndicator (2.0.0-beta.1)

It tries to build the Alamofire version 4.0.0-beta.2

Thanks,

Activity Indicator Not Working

I am using alamofire to call API. For Activity Controller I am installed this pod. In AppDelegate I import AlamofireNetworkActivityIndicator and in didFinishLaunchingWithOptions I wrote NetworkActivityIndicatorManager.shared.isEnabled = true. But when API is called from Alamofire the Indicator is not shown. Please let me know what wrong I have done?

Cannot call from an objective-c class

Hi.

I have a mixed app with swift and obj-c code. My AppDelegate is still in obj-c, so I tried to init the network indicator from obj-c. This does not work.

The generated "NetworkActivityIndicatorManager-Swift.h" file does not contain the class definition. I think this is because NetworkActivityIndicatorManager does not extend from NSObject.

I have created a small helper class in Swift:

import Foundation
import AlamofireNetworkActivityIndicator

class SwiftHelper : NSObject {

    func initNetworkIndicator()  {
        NetworkActivityIndicatorManager.sharedManager.isEnabled = true
    }
}

This class I can call from obj-c code. Is it possible to extend NetworkActivityIndicatorManager from NSObject?

Carthage compilation error with Xcode 10.2

What did you do?

Xcode 10.2

carthage bootstrap --platform iOS

What did you expect to happen?

Install AlamofireNetworkActivityIndicator from Carthage package manager

What happened instead?

Build Failed
Task failed with exit code 65:

Build system information
error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'AlamofireNetworkActivityIndicator')

** ARCHIVE FAILED **

Alamofire Environment

Alamofire version: 4.8.1
AlamofireNetworkActivityIndicator: 2.3.0
Xcode version: 10.2 (10E125)
Swift version: Swift 4.0 4.2 5.0
macOS version running Xcode: 10.14.3

minimum deployment target

Hello,
When I'm trying to install the pod I got error:
"Specs satisfying the AlamofireNetworkActivityIndicator (~> 2.0) dependency were found, but they required a higher minimum deployment target."

But now AlamofireNetworkActivityIndicator requirements is:
"iOS 8.0+
Xcode 8.0+
Swift 3.0+"
Alamofire 4.1 requirements is the same now and I successfully install Alamofire 4.1 via CocoaPods with "platform :ios, '8.0'" setting (in the Podfile and XCode project deployment target too) but I can't install AlamofireNetworkActivityIndicator with these correct settings.

Swift4 Package Manger

Cant build using swift package manger
error: package has unsupported layout; found loose source files: .build/checkouts/AlamofireNetworkActivityIndicator.git--6721799582381667356/Tests/NetworkActivityIndicatorManagerTests.swift

Error installing with Swift Package Manager

What did you do?

I tried to install from SPM with and without Alamofire 5.0.2 installed

What did you expect to happen?

The package installed

What happened instead?

Xcode shows me this error:

Showing All Messages
: terminated(128): /Applications/Xcode.app/Contents/Developer/usr/bin/git -C /Users/diego/Library/Developer/Xcode/DerivedData/TestAlamofire-gvqycjnmlwcnmvfowrhyoettyohc/SourcePackages/checkouts/AlamofireNetworkActivityIndicator submodule update --init --recursive output:
fatal: No url found for submodule path 'Carthage/Checkouts/Alamofire' in .gitmodules

Alamofire Environment

**Alamofire version: 5.0.2
**AlamofireNetworkActivityIndicator: 3.0.0
**Xcode version: 11.3.1 (11C504)
**Swift version: 5.1
**macOS version running Xcode: 10.15.3 (19D76)

Demo Project

Create a new empty project and try to install AlamofireNetworkActivityIndicator from SPM with or without Alamofire installed will show this error:

Captura de pantalla 2020-02-24 a las 13 30 58

Memory Leak on iOS 10.1.1

I added NetworkActivityIndicatorManager.shared.isEnabled = true in application:didFinishLaunchingWithOptions: in my AppDelegate and when I profile my app to check for memory leaks, Instruments indicates that there is a leak in NetworkActivityIndicatorManager on NSLock object.
I attach the stack trace of leak.
schermata 2016-11-10 alle 14 16 31

[SPM] Error resolving version 3.1.0 - missing macos platform - incompatible with Alamofire v5

What did you do?

Resolving and building Alamofire & AlamofireNetworkActivityIndicator with SPM, using the following package.swift:

import PackageDescription

let package = Package(
    name: "Networking",
    platforms: [
        .iOS(.v11),
        .macOS(.v10_12)
    ],
    products: [
        .library(
            name: "Networking",
            targets: ["Networking"]),
    ],
    dependencies: [
        .package(url: "https://github.com/Alamofire/Alamofire.git", .exact("5.1.0")),
        .package(url: "https://github.com/Alamofire/AlamofireNetworkActivityIndicator.git", .exact("3.1.0"))
    ],
    targets: [
        .target(
            name: "Networking",
            dependencies: [
                "Alamofire",
                "AlamofireNetworkActivityIndicator"],
            path: "Sources",
    ]
)

What did you expect to happen?

Both Alamofire & AlamofireNetworkActivityIndicator get resolved and built with command line:

swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios14.0-simulator"

What happened instead?

I get this error:

error: the library 'AlamofireNetworkActivityIndicator' requires macos 10.10, but depends on the product 'Alamofire' which requires macos 10.12; consider changing the library 'AlamofireNetworkActivityIndicator' to require macos 10.12 or later, or the product 'Alamofire' to require macos 10.10 or earlier.

What about adding the platform .macOS(.v10_12) to package.swift ?

Alamofire Environment

Alamofire version: 5.1.0
AlamofireNetworkActivityIndicator: 3.1.0
Xcode version: 13.0
Swift version: 5.5
macOS version running Xcode: 11.6

Demo Project

ActivityCount goes below 0 preventing the ActivityIndicator to show up

What did you do?

I was using the AlamofireImage swift library to download image thumbnails for a table view. I was also using this library to show the user network usage during the thumbnail downloading process.

What did you expect to happen?

Whenever a image thumbnail was being downloaded the network activity indicator would show up.

What happened instead?

Normally the activity indicator does show up, however when I scroll down the table view quickly, the activity indicator will no longer show up.

Further debugging I found that the activityCount in the NetworkActivityIndicatorManager would actually go in the negatives.

I found that there were more notifications calls Notification.Name.Task.DidComplete than the corresponding Notification.Name.Task.DidResume.

My suspicions are that when scrolling quickly through the list, the AlamofireImage library will eventually queue up the network requests as the maximumActiveDownloads limit has been reached. And because the cell which has an image that has been queued may not even start the download network request before it gets cancelled, as the cell is being recycled, the Notification.Name.Task.DidComplete gets called for the request, but it never did send the Notification.Name.Task.DidResume as it never got started.

The issue may in fact lie in the AlamofireImage library but wanted to bring it up here as the issue is noticeable with this library.

Example log

...
networkRequestDidStart = -9
networkRequestDidComplete = -10
networkRequestDidComplete = -11
networkRequestDidComplete = -12
networkRequestDidComplete = -13
networkRequestDidStart = -12
networkRequestDidStart = -11
networkRequestDidComplete = -12
networkRequestDidComplete = -13
networkRequestDidStart = -12
networkRequestDidComplete = -13
networkRequestDidStart = -12
networkRequestDidComplete = -13
...

Alamofire Environment

  • Xcode (9.4.1)
  • Mac OSX (10.13.5)
  • Swift 4.1
  • Devices running iOS 11+
  • Alamofire (4.7.2)
  • AlamofireImage (3.3.1)
  • AlamofireNetworkActivityIndicator (2.2.1)

Demo Project

Here's a link to a very basic project that should highlight the problem. I found the negative activityCount by adding print statements around the lines in the NetworkActivityIndicatorManager:

@objc private func networkRequestDidStart() {
        incrementActivityCount()
        print("networkRequestDidStart = \(activityCount)")
    }

    @objc private func networkRequestDidComplete() {
        decrementActivityCount()
        print("networkRequestDidComplete = \(activityCount)")
    }

GitHub Project

xCode 11 fails to archive the app

I have a problem when archiving my app, xcode remains blocked during the creation of the AlamofireNetworkActivityIndicator framework

Can't install AlamofireNetworkActivityIndicator

What did you do?

Specified the package version by adding pod 'AlamofireNetworkActivityIndicator', '~> 2.4' to my podfile, then ran pod install

What did you expect to happen?

I expect to install alamofire network activity indicator to use in my project

What happened instead?

Got an error, here is the output

[!] CocoaPods could not find compatible versions for pod "Alamofire":
  In snapshot (Podfile.lock):
    Alamofire (= 5.0.0-rc.3, ~> 5.0.0-rc.3)

  In Podfile:
    Alamofire (~> 5.0.0-rc.3)

    AlamofireNetworkActivityIndicator (~> 2.4) was resolved to 2.4.0, which depends on
      Alamofire (~> 4.8)

Alamofire Environment

Alamofire version: 5.0.0-rc.3
AlamofireNetworkActivityIndicator: 2.4
Xcode version: Version 11.3 (11C29)
Swift version: 5
macOS version running Xcode: 10.15.2(19C57)

Runloop is not thread-safe

It seem the lib add Timer to Runloop.main in network thread (generally not main thread).
But the document warning NSRunLoop is not thread safe.

The NSRunLoop class is generally not considered to be thread-safe and its methods should only be called within the context of the current thread. You should never try to call the methods of an NSRunLoop object running in a different thread, as doing so might cause unexpected results.

Core Foundation are generally thread-safe, use CFRunLoop* may be better.

Swift 3

Any plans to migrate to swift 3?

Carthage Build Error with Swift 5

What did you do?

I am migrating a custom NetworkFoundation that is based on Alamofire to Swift 5.

"carthage update" (to alamofire 5.0.0-beta.5)-> success
build in Xcode -> success

"carthage build --no-skip-current" -> error

What did you expect to happen?

The framework to build to then archive it with "carthage archive".

What happened instead?

*** Building scheme "Alamofire iOS" in Alamofire.xcworkspace
*** Building scheme "Alamofire macOS" in Alamofire.xcworkspace
*** Building scheme "Alamofire watchOS" in Alamofire.xcworkspace
*** Building scheme "Alamofire tvOS" in Alamofire.xcworkspace
*** Building scheme "MyNetworkFoundation" in MyNetworkFoundation.xcodeproj
*** Building scheme "Alamofire iOS" in Alamofire.xcworkspace
"Task failed with exit code 65."

In the logfile this is stated:
error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'Alamofire iOS') ** ARCHIVE FAILED **

What confuses me is that in my project under "Build Settings" the Swift version is set to 5. When I check in "/MyNetworkFoundation/Carthage/Checkouts/Alamofire/Alamofire.xcodeproj", the Swift version of all targets of is set to 5 too. I cannot spot Swift 3 anywhere in my framework nor Alamofire.

Alamofire Environment

Alamofire version: 5.0.0-beta.5
AlamofireNetworkActivityIndicator: -
Xcode version: 10.2.1
Swift version: 5.0
macOS version running Xcode: 10.14.5

Add Swift Package Manager support

Now that Xcode 11 supports Swift Package dependencies, it would be interesting to add the possibility to use this repository as Swift Package.

unsupported Swift 3.0

I cannot build it with Carthage because Xcode 10.2 doesn't support Swift 3.X. Could you upgrade it to minimum Swift 4.0 at least.

SWIFT_VERSION = 3.0;

App Crashed when integrating

What did you do?

Imported AlamofireNetworkActivityIndicator using carthage, and included

NetworkActivityIndicatorManager.shared.isEnabled = true

in appdelegate.
Gives me

1 commandlineflags.cc:1026] Ignoring RegisterValidateFunction() for flag pointer 0x10146ed98: no flag found at that address

What did you expect to happen?

Running smoothly

What happened instead?

App get crashed

Alamofire Environment

Alamofire version: 5.0.0-beta.5
AlamofireNetworkActivityIndicator: 2.4.0
Xcode version: 10.2.1
Swift version: 5
macOS version running Xcode: 10.14.3

NetworkActivityIndicator did not appear

ℹ Please fill out this template when filing an issue.
All lines beginning with an ℹ symbol instruct you with what info we expect. You can delete those lines once you've filled in the info.

Per our *CONTRIBUTING guidelines, we use GitHub for
bugs and feature requests, not general support. Other issues should be opened on Stack Overflow with the tag alamofire.

Please remove this line and everything above it before submitting.

What did you do?

I have enable below variable within AppDelegate.swift `s method: didFinishLaunchingWithOptions launchOptions:
NetworkActivityIndicatorManager.shared.isEnabled = true
NetworkActivityIndicatorManager.shared.startDelay = 1.0
NetworkActivityIndicatorManager.shared.completionDelay = 0.5

What did you expect to happen?

The ActivityIndicator appear

What happened instead?

nothing

Alamofire Environment

**Alamofire version: 4.7
**AlamofireNetworkActivityIndicator: 2.2
**Xcode version: 9.4.1
**Swift version: 4.1
**macOS version running Xcode:10.13.6

Demo Project

company project

Spinner can be left up indefinitely

The indicator works great. However there's a threading issue in decrementActivityCount().

This has a line:

guard activityCount > 0 else { return }

To prevent the activityCount going negative. (I'm curious why this line was introduced.) I have a situation where the activityCount would go negative. The debugger hits the else part of the guard. I believe the timing hole is around AlamoFire's resume() method.

AlamoFire's Request.resume() method (I added the comments):

public func resume() {
    if startTime == nil { startTime = CFAbsoluteTimeGetCurrent() }

    task.resume()

    // TIMING HOLE HERE. 
    // The task comes back fast (e.g. from cache) before we call postNotificationName. 
    // The decrement is called in the result callback, and activityCount should go to -1. (But doesn't due to the guard > 0)
    // Then this thread resumes and posts its notification about the task starting.
    // Now the activity indicator's count is 1... forever above zero, so the indicator stays on.
    NSNotificationCenter.defaultCenter().postNotificationName(Notifications.Task.DidResume, object: task)
}

I see no reason for the guard activityCount > 0 line. Removing it would fix this hole.

Separate AlamofireNetworkActivityIndicator from Alamofire?

Hi there! We were able to use AlamofireNetworkActivityIndicator without Alamofire by just removing the notification registration methods. I'd love to figure out a way to expose this class as its own framework in such a way that Alamofire users could still use this seamlessly as they do today, but folks like us could install a subspec that didn't require Alamofire. I'd be open to doing the work here too. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.