GithubHelp home page GithubHelp logo

peterfriese / makeitso Goto Github PK

View Code? Open in Web Editor NEW
475.0 16.0 83.0 709.53 MB

This is the source code for Make It So, the sample app accompanying my blog post "Replicating the iOS Reminders App Using SwiftUI and Firebase"

Home Page: https://twitter.com/peterfriese/status/1453467058302291975

License: Apache License 2.0

Swift 100.00%
swiftui firebase firestore ios ios-swift firebase-auth product-screenshot sign-in-with-apple combine-framework

makeitso's Introduction

Xcode Swift Contributors Forks Stargazers Issues MIT License


Logo

Make It So - Again!

This is the source code for Make It So, a sample app that demonstrates how to use Firebase in a SwiftUI app that runs on all (most) of Apple's platforms.
Follow along on Twitter as I code the app »

Report Bug · Request Feature

Getting started

This app requires a Firebase project, which you can create at no cost using the Firebase Console. Here are the steps. For a more detailed description of how to add Firebase to an iOS project, refer to the official Firebase docs for iOS and Apple's other platforms.

  1. Clone the repo
  2. Create a Firebase project
  3. Create a Cloud Firestore database in the new Firebase project (link)
  4. Enable Anonymous Authentication (link)
  5. Register the iOS app in the Firebase project
  6. Download the GoogleService-Info.plist file to the code/frontend/Configuration/Firebase/Development folder
  7. Open MakeItSo.xcodeproj in Xcode
  8. Select the MakeItSo (iOS) DEV target
  9. Run the app

About the project

License

See LICENSE

Disclaimer

This is not an official Google product.

Contact

Peter Friese - @peterfriese

Project Link: https://github.com/peterfriese/MakeItSo

Acknowledgements

The application icon is based on Check by Robert Won from the Noun Project

makeitso's People

Contributors

dependabot[bot] avatar peterfriese 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

makeitso's Issues

Refactor: rename Task to Reminder

This is mostly to avoid clashes with the new Task keyword in Swift 5.5, but also to avoid confusion about naming the data model Task in an app that replicates Apple's Reminders app.

Firestore read/write optimization or best practices

Hi Peter,

There is something that almost nobody is explaining/showing, at least with real code - how to optimize reads and writes to Firestore.
Currently, you know, if using Firestore, you always download all of the data (of a collection) on app launch, no matter if you are using one time fetch or a listener. Potentially you wanna have a lot of users, which on their side can have a lot of tasks. So, when these users start to use your app, you are going to have thousands of calls per day even though they might not be needed (no change in the data whatsoever).
My idea is if you can show us a valid way to cache the data and call for a refresh only when needed or there is a new data on the server.

Having problems to update ios13 code to ios14 (problems in FirebaseAuth + @main

Hi Peter, its me again. Im having a problem and didn't find an answer anywhere. First of all, I would like to apologize you
for posting this question here, but I didn't know where to post. After implementing some iOS 14 code, I updated my entire code to iOS 14 (before it was 13). But, with it came lot of error messages, with which I accidentally delete some stuff that stopped my code from updating when I changed it (it sucks that I didn't have any backup, and the ones I have appears to inherit the same errors). Then, I decided to create a new project, and add everything back again. However, the overall appearance of Xcode changed and I'm having problems in fixing them. The first one in related to the new @main struct (mine called MedicalApp). Before,in my code, the initial view was ContenView and it was exactly like this:

struct ContentView: View {

@EnvironmentObject var session: SessionStore

func getUser() {
    session.listen()
}
var body: some View {
    Group {
        if (session.session != nil) {
            HomeView()
        }
        else {
            SigninOrSignUp()
        }
    }
    .onAppear(perform: getUser)
}
}

Now, it appears that the main struct has changed to "projectName"App. Mine, is this one:

@main
 struct MedicalApp: App{
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene{
    WindowGroup{
        ContentView()
    }
}
}

With the same ContentView code as before.

These are my SessionStore, AppDelegate, SceneDelegate and SignInOrSignUpView that I copied exactly like the other code (you might have them from when I shared my code with you):

class SessionStore: ObservableObject{

   var didChange = PassthroughSubject<SessionStore, Never>()
   var session: User? {didSet {self.didChange.send(self)}}
  @Published var handle: AuthStateDidChangeListenerHandle?



   func listen() {
    
    handle = Auth.auth().addStateDidChangeListener({ (auth, user) in
        if let user = user {
            self.session = User(uid: user.uid, email: user.email)
        }
        else {
            self.session = nil
        }
    })
    }

   func signUp(email: String, password: String, handler: @escaping AuthDataResultCallback) {
    
    Auth.auth().createUser(withEmail: email, password: password, completion: handler)
   }



   func sigIn(email: String, password: String, handler: @escaping AuthDataResultCallback){
    
      Auth.auth().signIn(withEmail: email, password: password, completion: handler)
    
   }

  func signOut() {
    
    do {
        try Auth.auth().signOut()
        self.session = nil
    }
    catch  {
        print("Erro ao sair")
    }
}
func showError(_ message: String) {
    
}

func unbind() {
    
    if let handle = handle{
        Auth.auth().removeStateDidChangeListener(handle)
    }
}
deinit {
    unbind()
  }


   }

  class AppDelegate: UIResponder, UIApplicationDelegate , GIDSignInDelegate {

     var window: UIWindow?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions  launchOptions:      [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
      FirebaseApp.configure()
    GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
    GIDSignIn.sharedInstance().delegate = self

    return true
    }


           func application(_ application: UIApplication, open url: URL, options:   [UIApplication.OpenURLOptionsKey : Any])
    -> Bool {
   return GIDSignIn.sharedInstance().handle(url)
  }

     func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?)      {
  // ...
  if let error = error {
    print(error.localizedDescription)
    return
  }

  guard let authentication = user.authentication else { return }
  let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                    accessToken: authentication.accessToken)
    Auth.auth().signIn(with: credential) { (res, err) in
        if err != nil{
            print((err?.localizedDescription)!)
            return
        }
        print("usuário=" + (res?.user.email)!)
    }
    
    
}

func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
    // Perform any operations when the user disconnects from app here.
    // ...
}

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
  }

 class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?


func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    let contentView = ContentView()
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: contentView.environmentObject(SessionStore()))
        self.window = window
        window.makeKeyAndVisible()
    }
}

func sceneDidDisconnect(_ scene: UIScene) {
    
}

func sceneDidBecomeActive(_ scene: UIScene) {
   
}

func sceneWillResignActive(_ scene: UIScene) {
    
}

func sceneWillEnterForeground(_ scene: UIScene) {
   
}

func sceneDidEnterBackground(_ scene: UIScene) {
    
}
 }



struct SigninOrSignUp: View {

var body: some View {
    
    ZStack{
               LinearGradient(gradient: .init(colors: [Color("Color"),Color("Color1"),Color("Color2")]), startPoint: .top
            , endPoint: .bottom)
            .edgesIgnoringSafeArea(.all)
        
        if UIScreen.main.bounds.height > 800{
            
            SignView()
        }
        else{
            
            ScrollView(.vertical, showsIndicators: false) {
                
                SignView()
            }
        }
    
    }
 }
  }

*SignView is the main view for Signin and Signup

*Above AppDelegate, I had @UIApplicationMain. It had to be deleted because there was an error saying there were multiple main (possibly referring to @main in struct MedicalApp: App).

The building succeeds, but the screen starts all white and then turns to all black.

Questions:
Do I need to maintain "projectName"App? If I delete it, how to turn ContentView the main one (tried @main but didn't work because it needed a main static function)?
How to fix these problem? How to make them work again?

--> If you still have the code I shared with you it would be great if you shared it back with me, as I deleted the repo because it was public.

After some time, this appeared on output:
2020-11-06 18:26:14.273193-0300 MedicalApp[22684:253294] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
2020-11-06 18:26:15.830546-0300 MedicalApp[22684:253306] 7.0.0 - [Firebase/Analytics][I-ACS023007] Analytics v.7.0.0 started
2020-11-06 18:26:16.169322-0300 MedicalApp[22684:253306] 7.0.0 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see "gooleLink")
2020-11-06 18:26:22.776226-0300 MedicalApp[22684:253306] 7.0.0 - [Firebase/Analytics][I-ACS800023] No pending snapshot to activate. SDK name: app_measurement
2020-11-06 18:26:29.967694-0300 MedicalApp[22684:253350] 7.0.0 - [Firebase/Analytics][I-ACS023012] Analytics collection enabled
2020-11-06 18:26:29.977395-0300 MedicalApp[22684:253350] 7.0.0 - [Firebase/Analytics][I-ACS023220] Analytics screen reporting is enabled. Call +[FIRAnalytics logEventWithName:FIREventScreenView parameters:] to log a screen view event. To disable automatic screen reporting, set the flag FirebaseAutomaticScreenReportingEnabled to NO (boolean) in the Info.plist

Fix widget layout issues

General

  • Adjust icon size
  • Adjust size of number of tasks label
  • Adjust task title font size

Large widget

  • Align task list to top

Medium widget

  • Add spacing to left of task list

Improve focus handling

If focus is in an empty cell and the user hits the enter key (or performs any other action that removes focus from the cell), remove the empty task. This is in line with the Reminders app.

signInWithAppleButtonTapped - make the default method 'signIn' ?

Testing in Xcode 12.4, iOS 14.4, following this tutorial (awesome stuff by the way!)

In SignInView.swift, when calling signInWithAppleButtonTapped, I noticed the .link option is use for the signInHandler state...

In AuthenticationService.swift, inside caseAuth.auth().currentUser was always returned nil for me (presumably because it's always logged in as an anonymous user before?)

I changed signInWithAppleButtonTapped to be .signIn, and the App logs in ok:

  func signInWithAppleButtonTapped() {
    signInHandler = SignInWithAppleCoordinator(window: self.window)
    signInHandler?.signIn { (user) in
      print("User signed in. UID: \(user.uid), email: \(user.email ?? "(empty)")")
      self.presentationMode.wrappedValue.dismiss()
    }
  }

So I wonder whether for the example code it makes sense to have .signIn as the state option, and a separate button flow for linking accounts?

Xcode swift compiler crashes building final project

I'm using Xcode Version 11.3.1 and I followed the instructions. The pods all installed ok, but when I attempted to build, the Swift compiler crashes (I think). I've left off the program arguments, but here's the crash info:

1.	While running pass #0 SILModuleTransform "SerializeSILPass".
2.	While serializing 'id' (at /Users/anders/Documents/dev/Open-Source-iOS/MakeItSo/final/MakeItSo/MakeItSo/Models/Task.swift:19:8)
0  swift                    0x000000010f8c3a63 PrintStackTraceSignalHandler(void*) + 51
1  swift                    0x000000010f8c3236 SignalHandler(int) + 358
2  libsystem_platform.dylib 0x00007fff6ba74b5d _sigtramp + 29
3  libsystem_platform.dylib 000000000000000000 _sigtramp + 2488841408
4  swift                    0x000000010c40e066 swift::ParamDecl::getDefaultValueStringRepresentation(llvm::SmallVectorImpl<char>&) const + 1014
5  swift                    0x000000010c19526a swift::serialization::Serializer::writeDecl(swift::Decl const*) + 5946
6  swift                    0x000000010c1bad0f swift::serialization::Serializer::writeAllDeclsAndTypes() + 62287
7  swift                    0x000000010c1c7cd4 swift::serialization::Serializer::writeAST(llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, bool) + 5364
8  swift                    0x000000010c1d4c10 swift::serialization::Serializer::writeToStream(llvm::raw_ostream&, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::SILModule const*, swift::SerializationOptions const&) + 6016
9  swift                    0x000000010c1d64eb bool llvm::function_ref<bool (llvm::raw_pwrite_stream&)>::callback_fn<swift::serialize(llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::SerializationOptions const&, swift::SILModule const*)::$_8>(long, llvm::raw_pwrite_stream&) + 139
10 swift                    0x000000010b4db279 swift::withOutputFile(swift::DiagnosticEngine&, llvm::StringRef, llvm::function_ref<bool (llvm::raw_pwrite_stream&)>) + 2569
11 swift                    0x000000010c1d6347 swift::serialize(llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::SerializationOptions const&, swift::SILModule const*) + 311
12 swift                    0x000000010b516d0b std::__1::__function::__func<performCompileStepsPostSILGen(swift::CompilerInstance&, swift::CompilerInvocation&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, bool, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, bool, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*)::$_12, std::__1::allocator<performCompileStepsPostSILGen(swift::CompilerInstance&, swift::CompilerInvocation&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, bool, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, bool, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*)::$_12>, void ()>::operator()() + 603
13 swift                    0x000000010bcc0551 SerializeSILPass::run() + 49
14 swift                    0x000000010bbb69c9 swift::SILPassManager::execute() + 7305
15 swift                    0x000000010b81369b swift::CompilerInstance::performSILProcessing(swift::SILModule*, swift::UnifiedStatsReporter*) + 1563
16 swift                    0x000000010b50cec5 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 33925
17 swift                    0x000000010b501234 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 6820
18 swift                    0x000000010b48e733 main + 1219
19 libdyld.dylib            0x00007fff6b8893d5 start + 1
20 libdyld.dylib            0x00000000000000c2 start + 2490854638
error: Segmentation fault: 11 (in target 'MakeItSo' from project 'MakeItSo')

Where is updateTask called?

I am new to SwiftUI and followed along with this tutorial, well part 1 mostly but I can't see any code that calls the updateTask function.

I have edited the code to suit a app am working on and this is the only thing I can't get working (editing a task) but then I realised updateTask doesn't seem to be used any where.

Sorry I can't seem to mark this post as a question.

Migrating user data

Thanks for the great tutorial.
I would really like to see that last piece come into play, which is the migration of the anonymous user data in case a user reinstalls the apps, makes more changes even though he has signed up before, and then tries to sign in again. Do you think you could add this in a separate post or point to a solution?

WatchStream Stream error: 'Unavailable: Network connectivity changed'

When login into iCloud account, the final step fails with:

WatchStream (6000006dc718) Stream error: 'Unavailable: Network connectivity changed'
Sign in with Apple errored: The operation couldn’t be completed. (com.apple.AuthenticationServices.AuthorizationError error 1001.)

This is from base code on this commit.

[Feature Request] - Sharing lists with other users

One of the features I love most about the Reminders app, is the ability to share a List with another user.

(I noticed you've already added this as a bullet point here: "Sharing lists with other users"

Would be amazing if you could write up a tutorial on how to do this - thanks!

New task text disappearing

Hi - thanks for sharing this code.

Xcode: 11.4.1
Simulator: iPhone 11 / iOS 13.4.1

I am seeing an issue when adding a new task - after typing in the task text and tapping return on simulator keyboard or enter on the actual computer keyboard, the new row disappears. I verified the task is showing up in Firebase right away. If you kill the app and re-open, the task then shows up. I am also seeing this on my iPhone with iOS 13.3.1. Was wondering if you can reproduce this issue. Thanks so much.

Nick

[Part 3] Small copy error

Looking at one of the snippets in the 3rd blog post:

class AuthenticationService: ObservableObject {
  // ...
  func updateDisplayName(displayName: String) { // (2)
    if let user = Auth.auth().currentUser {
      let changeRequest = user.createProfileChangeRequest() // (3)
      changeRequest.displayName = displayName
      changeRequest.commitChanges { error in // (4)
        if error != nil {
          print("Successfully updated display name for user [\(user.uid)] to [\(displayName)]")
        }
      }
    }
  }
}

I think this is a typo? Should be error == nil:

if error != nil {
          print("Successfully updated display name for user [\(user.uid)] to [\(displayName)]")

Bug in Resolver code block on website

Hi! Thanks again for this great guide! I found a bug with the Resolver code block missing a .

In your article: https://peterfriese.dev/replicating-reminder-swiftui-firebase-part1/#binding-the-view-models

In the code block below, application should be .application

// File: AppDelegate+Resolving.swift

extension Resolver: ResolverRegistering {
  public static func registerAllServices() {
    register { TestDataTaskRepository() as TaskRepository }.scope(application)
  }
}

like so:

// File: AppDelegate+Resolving.swift

extension Resolver: ResolverRegistering {
  public static func registerAllServices() {
    register { TestDataTaskRepository() as TaskRepository }.scope(.application)
  }
}

Simple fix got me going, but had me scratching my head as a new swift developer. If you don't want me to make issues here based on your website let me know and I will stop the feedback :)

Thanks again for the help! This article has been super helpful, and I am excited for the next few sections.

Use plain list style on task list

In iOS 14.0 b1, SwiftUI defaults to displaying lists with rounded corners:

Default List Style

Instead, display the list so the individual rows go from edge to edge, just like in iOS 13:

Plain List STyle

Styling NavigationBar

To style a navigation bar, you can do something like this

struct TaskListView: View {
    init() {
      UINavigationBar.appearance().largeTitleTextAttributes = [
        .foregroundColor: UIColor.systemRed
     ]
  }

    ... rest of struct

I would make a PR but to build using master requires the Google plist file for firebase.

Use TestDataTaskRepository in View Preview

Hi,

first of all thanks for your great work. It is really a massive help for someone just starting with SwiftUI and Firebase.

I was looking for a solution to keep the TestDataTaskRepository providing the Data for the preview of the TaskListView so making changes to the cell still becomes visible while running the app uses the Firebase repository - as I am quite new to SwiftUI and especially Resolver if couldn't figure it out.

Thank you in advance.

Kind reagards

Cannot save @DocumentID properties to disk

Learning a lot from your demo app's structure, how I have an issue with saving some test data to disk.

When using the LocalTaskRepository, it creates a json file for your test data, but you cannot use the wrapper @documentid when doing standard encoding - so the app crashes.

This is expected, as per the docs, but is there away you would approach this ? Having test data sources, with the great swap in / out repos thanks to Resolver would be great.

What do you suggest to make it work ? Hopefully I didn't miss something in your articles.

Thanks

Sign In with Apple doesn’t work

With the new update of Swift 5.2 the final app no longer allows.

Error is any the user has logged out, even though the user hasn’t ever logged in.

All settings have been cleared, new iPhone install, new Firebase project, app id and applied websites cleared.

Error still persists.

Sign In with Apple doesn't work with ios 14 Simulator

Hi, this seems like bug with Xcode 12/ios 14 simulator, but Apple Sign in doesn't work in ios-14 simulator using this project code. When entering the password the screen just hangs and nothing happens.
With log:
2020-07-02 17:09:07.433852+0300 byan[86378:2354436] 6.27.0 - [Firebase/Firestore][I-FST000001] WatchStream (60000368b218) Stream error: 'Unavailable: Network connectivity changed'
2020-07-02 17:09:17.206022+0300 byan[86378:2354436] [core] Authorization failed: Error Domain=AKAuthenticationError Code=-7071 "(null)"
Sign in with Apple errored: The operation couldn’t be completed. (com.apple.AuthenticationServices.AuthorizationError error 1000.)

But it works fine with ios-13. I'm using Xcode 12 MacOs Catalina 10.15.5.

FR: Implement lists

Currently, MakeItSo stores all tasks in a single list per user. To make managing tasks more flexible, MakeItSo should support adding tasks to lists.

In the spirit of MakeItSo being a replica of the iOS Reminders app, here are a couple of assumptions:

  • lists can have any number of tasks
  • lists are not nested
  • support sharing lists with other people
  • lists have a name, an icon, and an accent color
  • users can specify the ordering of lists
  • there are 4 special lists
    • All: shows all tasks
    • Today: this list shows all tasks that are due today
    • Scheduled: this list shows all tasks that have a due date, grouped by date
    • Flagged: : this list shows all tasks that are marked as flagged

[Feature Request] Thank you!

First of all, wanted to thank you for the awesome tutorial series you have been working on. They have the right amount of detail and depth to make it easy to follow along and also building something beyond the trivial hello world. Both in the SwiftUI as well as in the Firebase side.

On the Firebase side of things I was thinking that it would be interesting to see some use of querying/filtering and possibly cloud functions.

On the iOS side of the project maybe a Today Widget Extension or a Siri Extension would be a neat next feature.

Again, thanks for all the work!

P.S. A small suggestion for the blog posts, when you show partial code implementations of features it would be helpful to link to the github source file, so that actually seeing the whole implementation/source code would help fill in the gaps. I didn't clone the repo and I'm just coding as I follow the tutorial and changing things here and there to make sure I really understand the concepts and being able to peek at the source would be helpful.

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.