Nuxtstop

For all things nuxt.js

Getting started with Appwrite's Apple SDK and UIKit

Getting started with Appwrite's Apple SDK and UIKit
34 0

One of the major highlights of Appwrite 0.11 is the official support for iOS, macOS, tvOS and watchOS. We've also released a brand-new Apple SDK to go alongside it! 😉

Appwrite & Swift

In this tutorial, we'll learn to set up Appwrite's Apple SDK, interact with Appwrite's Accounts API and also learn to set up OAuth Logins in your App. Let's get started!

We'll use UIKit in this tutorial, if you're using SwiftUI, check out this tutorial instead.

📝 Prerequisites

At this stage, we assume that you already have an Appwrite instance up and running. If you do not have Appwrite setup yet, you can follow the super easy installation step over at appwrite.io. It's not a typo. There really is only 1 step!

You should have also set up an OAuth provider with Appwrite to be able to follow the OAuth section of this tutorial. You can learn to set up OAuth providers in Appwrite with this tutorial.

🛠️ Create a new App Project

Create a new iOS > App in Xcode, selecting Storyboard for Interface and UIKit App Delegate for Life Cycle.

Create Project

With the app created, now is also a good time to add our iOS, macOS, watchOS or tvOS app as a platform in the Appwrite Console. Head over to your project file and find your Bundle Identifier. It should look something like io.appwrite.Appwrite-iOS.

In your Appwrite console, click on Add Platform and select a New Apple App, then one of the iOS, macOS, watchOS or tvOS tabs. Give your app a name, add the bundle identifier and click Register.

Once this is complete, it's time to head back to our Xcode project add our dependencies.

👷 Setup Appwrite's Apple SDK

Using Xcode

The Appwrite Apple SDK is available via Swift Package Manager. In order to use the Appwrite Apple SDK from Xcode, select File > Swift Packages > Add Package Dependency. In the dialog that appears, enter the Appwrite Apple SDK package URL and click Next.

Once the repository information is loaded, add your version rules and click Next again.

Set Package Version

On the final screen, make sure Appwrite is selected to add to your target as a library.

Link To Target

Using Swift Package Manager

Add the package to your Package.swift dependencies:

    dependencies: [
        .package(url: "https://github.com/appwrite/sdk-for-apple", from: "0.1.0"),
    ],
Enter fullscreen mode Exit fullscreen mode

Then add it to your target:

    targets: [
        .target(
            name: "[YourAppTarget]",
            dependencies: [
                .product(name: "Appwrite", package: "sdk-for-apple")
            ]
        ),
Enter fullscreen mode Exit fullscreen mode

Build your project and if there are no errors, we're ready to proceed!

🏗️ Create the ViewController

Create a new file ViewController.swift and add the following. This defines our controller for our storyboard and sets up our button click listeners that will call the ViewModel.

import Appwrite
import NIO
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var text: UITextView!
    @IBOutlet weak var register: UIButton!
    @IBOutlet weak var loginButton: UIButton!
    @IBOutlet weak var logOutButton: UIButton!
    @IBOutlet weak var getUserButton: UIButton!
    @IBOutlet weak var loginWithFacebook: UIButton!

    let client = Client()
        .setEndpoint("http://localhost/v1")
        .setProject("613b18dabf74a")
        .setSelfSigned()

    lazy var account = Account(client)

    var picker: ImagePicker?

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    @IBAction func register(_ sender: Any) {
        account.create(email: "tester@appwrite.io", password: "password") { result in
            var string: String = ""

            switch result {
            case .failure(let error): string = error.message
            case .success(let user): string = user.email
            }

            DispatchQueue.main.async {
                self.text.text = string
            }
        }
    }

    @IBAction func login(_ sender: Any) {
        account.createSession(email: "tester@appwrite.io", password: "password") { result in
            var string: String = ""

            switch result {
            case .failure(let error): string = error.message
            case .success(let session): string = session.userId
            }

            DispatchQueue.main.async {
                self.text.text = string
            }
        }
    }

    @IBAction func loginWithFacebook(_ sender: UIButton) {
        // To be added later.
    }

    @IBAction func getUser(_ sender: Any) {
        account.get { result in
            var string = ""

            switch result {
            case .failure(let error): string = error.message
            case .success(let user): string = user.email
            }

            DispatchQueue.main.async {
                self.text.text = string
            }
        }
    } 

    @IBAction func logOut(_ sender: Any) {
        account.deleteSession(sessionId: "current") { result in
            var string = ""

            switch result {
            case .failure(let error): string = error.message
            case .success(let success): string = String(describing: success)
            }

            DispatchQueue.main.async {
                self.text.text = string
            }
        }
    } 
}
Enter fullscreen mode Exit fullscreen mode

Our ViewController has 4 state functions:

  • register - click handler for the Signup Button
  • login - click handler for the Login Button
  • logout - click handler for the Logout Button
  • getUser - click handler for the Get User Button

You should now be able to run your app and create users, login, logout and get information about the currently logged-in user!

🔐 Adding OAuth Support

You would have noticed that we have a Login With Facebook button in our UI, but it doesn't do anything yet; let's now add Facebook OAuth to our app!

The first step is to add a callback URL scheme to our Info.plist file.

<key>CFBundleURLTypes</key>
<array>
<dict>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>CFBundleURLName</key>
    <string>io.appwrite</string>
    <key>CFBundleURLSchemes</key>
    <array>
        <string>appwrite-callback-[PROJECT-ID]</string>
    </array>
</dict>
</array>
Enter fullscreen mode Exit fullscreen mode

Make sure you replace the Project ID in appwrite-callback-[PROJECT-ID] with your own.

Next we need to add a hook to save cookies when our app is opened by its callback URL. To do this, add the following function to your SceneDelegate.swift. If you have already defined this function, you can just add the contents below.

    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url,
            url.absoluteString.contains("appwrite-callback") else {
            return
        }
        WebAuthComponent.handleIncomingCookie(from: url)
    }
Enter fullscreen mode Exit fullscreen mode

The last step is to invoke the SDK function createOAuth2Session from AccountViewController.swift from our existing button's action.

    @IBAction func loginWithFacebook(_ sender: UIButton) {
        account.createOAuth2Session(
            provider:"facebook",
            success: "https://demo.appwrite.io/auth/oauth2/success",
            failure: "https://demo.appwrite.io/auth/oauth2/failure") { result in
                var string: String = ""

                switch result {
                case .failure(let error): string = error.message
                case .success(let response): string = response.description
                }

                DispatchQueue.main.async {
                    self.text.text = string
                }
            }
    }
Enter fullscreen mode Exit fullscreen mode

Re-run your app and you should now be able to trigger your Facebook OAuth Flow! With that, you now know how to interact with Appwrite's Accounts API in your iOS, macOS, tvOS and watchOS apps!

We've built a complete app that interacts with all of Appwrite's APIs, which you can find over at our Github Repo. If you'd like to learn more about Appwrite or how Appwrite works under the hood, we've just curated all the resources for you during 30 Days of Appwrite.

✨️ Credits

Hope you enjoyed this article! We love contributions and encourage you to take a look at our open issues and ongoing RFCs.

If you get stuck anywhere, feel free to reach out to us on our friendly support channels run by humans 👩‍💻.

Here are some handy links for more information: