Getting started with Appwrite's Apple SDK and SwiftUI
Tags: ios, swift, tutorial, news
Published: 2021-10-18 18:21:59

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! 😉

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z57is2vh5f81zomtmhpe.png)
 

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 [SwiftUI](https://developer.apple.com/xcode/swiftui/) in this tutorial, if you're using UIKit, check out <a href="https://dev.to/appwrite/getting-started-with-appwrites-apple-sdk-and-uikit-4bjd">this tutorial</a> 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](https://appwrite.io/docs/installation). 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](https://dev.to/appwrite/30daysofappwrite-oauth-providers-3jf6).

## 🛠️ Create a new App Project

Create a new **Multiplatform > App** in Xcode.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bccme991eygpapfa11ww.png)
   

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 and 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](https://github.com/appwrite/sdk-for-apple) and click **Next**.

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ngnb4wjvojs8ya6qpccg.png)
 

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kr3up1r47b7hcqjoddpf.png)
 


### Using Swift Package Manager

Add the package to your `Package.swift` dependencies:

```swift
    dependencies: [
        .package(url: "https://github.com/appwrite/sdk-for-apple", from: "0.1.0"),
    ],
```

Then add it to your target:

```swift
    targets: [
        .target(
            name: "[YourAppTarget]",
            dependencies: [
                .product(name: "Appwrite", package: "sdk-for-apple")
            ]
        ),
```

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

## 🏗️ Create the layouts

Create a new file `AccountView.swift` and add the following. This defines our SwiftUI view and sets up our buttons and their click listeners that will call the `ViewModel`.

```swift
import SwiftUI
import Appwrite
import NIO

let host = "http://localhost:80/v1"
let projectId = "613b18dabf74a"

let client = Client()
    .setEndpoint(host)
    .setProject(projectId)
    .setSelfSigned()

struct AccountView: View {
    
    @ObservedObject var viewModel: ViewModel
    
    var body: some View {
     
        VStack(spacing: 8) {
        
            viewModel.downloadedImage?
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(height: 200)
                
            TextEditor(text: viewModel.$response)
                .padding()
            TextEditor(text: viewModel.$email)
                .padding()
            TextEditor(text: viewModel.$password)
                .padding()
            TextEditor(text: viewModel.$name)
                .padding()
            Button("Login") {
                viewModel.login()
            }
            Button("Login with Facebook") {
                // We'll add this later
            }
            Button("Register") {
                viewModel.register()
            }
            Button("Get User") {
                viewModel.getUser()
            }
            Button("Log Out") {
                viewModel.logOut()
            }
        }
        .registerOAuthHandler()
    }

}

struct ExampleView_Previews: PreviewProvider {
    static var previews: some View {
        ExampleView(viewModel: ExampleView.ViewModel())
    }
}
```

## 🔨 Create the ViewModel

Let's now create a ViewModel `AccountViewModel.swift` to manage state and interact with the Appwrite SDK in response to UI interactions.

```swift
import Foundation
import SwiftUI
import Appwrite
import NIO

extension AccountView {
    
    class ViewModel : ObservableObject {
    
        let account = Account(client)

        @State var email: String = "test@test.test"
        @State var password: String = "password"
        @State var name: String = "Name"
        @State var response: String = ""
        
        func register() {
            account.create(email: email, password: password) { result in
                switch result {
                case .failure(let error): self.response = error.message
                case .success(let user): self.response = user.email
                }
            }
        }
        
        func login() {
            account.createSession(email: email, password: password) { result in
                switch result {
                case .failure(let error): self.response = error.message
                case .success(let session): self.response = session.userId
                }
            }
        }
        
        func getUser() {
            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
                }
            }
        }
        
        func logOut() {
            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
                }
            }
        }
    }
}
```

Our ViewModel has 4 state objects:

- email
- name
- password
- response

We also have 4 functions to interact with the Appwrite SDK:

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

## 🔧 Update The Application File

Finally, let's update our `AccountApp.swift`, which will initialise our application and create the `AccountView` and `AccountViewModel`.

```swift
import SwiftUI

@main
struct AccountApp: App {
    var body: some Scene {
        WindowGroup {
            AccountView(viewModel: AccountView.ViewModel())
        }
    }
}

```

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.

```xml
<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>
```

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

Next, we'll add a function to our ViewModel to call the `createOAuth2Session()` method of the Appwrite SDK.

```swift
func loginWithFacebook() {
    account.createOAuth2Session(
        "facebook",
        "\(host)/auth/oauth2/success",
        "\(host)/auth/oauth2/failure"
    ) { result in
        switch result {
        case .failure: self.response = "false"
        case .success(let success): self.response = success.description
        }
    }
}
```

The last step is to invoke this function from `AccountView.swift`, calling the function from our existing button's action.

```swift
Button("Login with Facebook") {
    viewModel.loginWithFacebook()
}
```

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](https://github.com/appwrite/playground-for-apple-swiftui). 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](https://30days.appwrite.io/).

## ✨️ Credits

Hope you enjoyed this article! We love contributions and encourage you to take a look at our [open issues](https://github.com/appwrite/appwrite/issues) and [ongoing RFCs](https://github.com/appwrite/rfc/pulls).

If you get stuck anywhere, feel free to reach out to us on our [friendly support channels](https://appwrite.io/discord) run by humans 👩‍💻.

Here are some handy links for more information:

- [Appwrite Contribution Guide](https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md)
- [Appwrite Github](https://github.com/appwrite)
- [Appwrite Documentation](https://appwrite.io/docs)