Merge pull request #64 from appwrite/dev

release: apple
This commit is contained in:
Luke B. Silver
2024-12-18 09:57:13 +00:00
committed by GitHub
65 changed files with 200 additions and 350 deletions
+11
View File
@@ -0,0 +1,11 @@
name: Auto-close External Pull Requests
on:
pull_request_target:
types: [opened, reopened]
jobs:
auto_close:
uses: appwrite/.github/.github/workflows/autoclose.yml@main
secrets:
GH_AUTO_CLOSE_PR_TOKEN: ${{ secrets.GH_AUTO_CLOSE_PR_TOKEN }}
+1 -1
View File
@@ -31,7 +31,7 @@ Add the package to your `Package.swift` dependencies:
```swift
dependencies: [
.package(url: "git@github.com:appwrite/sdk-for-apple.git", from: "7.0.0"),
.package(url: "git@github.com:appwrite/sdk-for-apple.git", from: "7.1.0"),
],
```
+8 -8
View File
@@ -23,7 +23,7 @@ open class Client {
"x-sdk-name": "Apple",
"x-sdk-platform": "client",
"x-sdk-language": "apple",
"x-sdk-version": "7.0.0",
"x-sdk-version": "7.1.0",
"x-appwrite-response-format": "1.6.0"
]
@@ -464,23 +464,23 @@ open class Client {
if param is String
|| param is Int
|| param is Float
|| param is Double
|| param is Bool
|| param is [String]
|| param is [Int]
|| param is [Float]
|| param is [Double]
|| param is [Bool]
|| param is [String: Any]
|| param is [Int: Any]
|| param is [Float: Any]
|| param is [Double: Any]
|| param is [Bool: Any] {
encodedParams[key] = param
} else {
let value = try! (param as! Encodable).toJson()
let range = value.index(value.startIndex, offsetBy: 1)..<value.index(value.endIndex, offsetBy: -1)
let substring = value[range]
encodedParams[key] = substring
} else if let encodable = param as? Encodable {
encodedParams[key] = try encodable.toJson()
} else if let param = param {
encodedParams[key] = String(describing: param)
}
}
+47 -10
View File
@@ -2,8 +2,8 @@ import AsyncHTTPClient
import Foundation
import NIO
#if canImport(SwiftUI)
import SwiftUI
#if canImport(AuthenticationServices)
import AuthenticationServices
#endif
///
@@ -13,12 +13,10 @@ import SwiftUI
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, visionOS 1.0, *)
public class WebAuthComponent {
#if canImport(SwiftUI)
@Environment(\.openURL)
private static var openURL
#endif
private static var callbacks = [String: (Result<String, AppwriteError>) -> Void]()
#if canImport(AuthenticationServices)
private static var currentAuthSession: ASWebAuthenticationSession?
#endif
///
/// Authenticate Session with OAuth2
@@ -41,9 +39,29 @@ public class WebAuthComponent {
) {
callbacks[callbackScheme] = onComplete
#if canImport(SwiftUI)
openURL(url)
#endif
#if canImport(AuthenticationServices)
currentAuthSession = ASWebAuthenticationSession(
url: url,
callbackURLScheme: callbackScheme
) { callbackURL, error in
if let error = error {
cleanUp()
} else if let callbackURL = callbackURL {
// handle cookies here itself!
WebAuthComponent.handleIncomingCookie(from: callbackURL)
cleanUp()
}
}
if let session = currentAuthSession {
/// Indicates that the session should be a private session.
session.prefersEphemeralWebBrowserSession = true
session.presentationContextProvider = PresentationContextProvider.shared
session.start()
} else {
print("Failed to create ASWebAuthenticationSession")
}
#endif
}
///
@@ -130,5 +148,24 @@ public class WebAuthComponent {
callbacks.forEach { (_, callback) in
callback(.failure(AppwriteError(message: "User cancelled login.")))
}
#if canImport(AuthenticationServices)
currentAuthSession = nil
#endif
}
}
#if canImport(AuthenticationServices)
/// Presentation context for the ASWebAuthenticationSession.
class PresentationContextProvider: NSObject, ASWebAuthenticationPresentationContextProviding {
static let shared = PresentationContextProvider()
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
if let mainWindow = OSApplication.shared.windows.first { $0.isKeyWindow } {
return mainWindow
}
return ASPresentationAnchor()
}
}
#endif
+25 -17
View File
@@ -214,7 +214,7 @@ open class Account: Service {
}
///
/// List Identities
/// List identities
///
/// Get the list of identities for the currently logged in user.
///
@@ -402,7 +402,7 @@ open class Account: Service {
}
///
/// Create Authenticator
/// Create authenticator
///
/// Add an authenticator app to be used as an MFA factor. Verify the
/// authenticator using the [verify
@@ -439,7 +439,7 @@ open class Account: Service {
}
///
/// Verify Authenticator
/// Verify authenticator
///
/// Verify an authenticator app after adding it using the [add
/// authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator)
@@ -480,7 +480,7 @@ open class Account: Service {
}
///
/// Verify Authenticator
/// Verify authenticator
///
/// Verify an authenticator app after adding it using the [add
/// authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator)
@@ -503,7 +503,7 @@ open class Account: Service {
}
///
/// Delete Authenticator
/// Delete authenticator
///
/// Delete an authenticator for a user by ID.
///
@@ -531,7 +531,7 @@ open class Account: Service {
}
///
/// Create MFA Challenge
/// Create MFA challenge
///
/// Begin the process of MFA verification after sign-in. Finish the flow with
/// [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge)
@@ -568,7 +568,7 @@ open class Account: Service {
}
///
/// Create MFA Challenge (confirmation)
/// Create MFA challenge (confirmation)
///
/// Complete the MFA challenge by providing the one-time password. Finish the
/// process of MFA verification by providing the one-time password. To begin
@@ -604,7 +604,7 @@ open class Account: Service {
}
///
/// List Factors
/// List factors
///
/// List the factors available on the account to be used as a MFA challange.
///
@@ -635,7 +635,7 @@ open class Account: Service {
}
///
/// Get MFA Recovery Codes
/// Get MFA recovery codes
///
/// Get recovery codes that can be used as backup for MFA flow. Before getting
/// codes, they must be generated using
@@ -669,7 +669,7 @@ open class Account: Service {
}
///
/// Create MFA Recovery Codes
/// Create MFA recovery codes
///
/// Generate recovery codes as backup for MFA flow. It's recommended to
/// generate and show then immediately after user successfully adds their
@@ -704,7 +704,7 @@ open class Account: Service {
}
///
/// Regenerate MFA Recovery Codes
/// Regenerate MFA recovery codes
///
/// Regenerate recovery codes that can be used as backup for MFA flow. Before
/// regenerating codes, they must be first generated using
@@ -1350,12 +1350,16 @@ open class Account: Service {
let callbackScheme = "appwrite-callback-\(client.config["project"] ?? "")"
_ = try await withCheckedThrowingContinuation { continuation in
WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in
continuation.resume(with: result)
/// main thread for PresentationContextProvider
DispatchQueue.main.async {
WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in
continuation.resume(with: result)
}
}
}
return true
}
///
@@ -1849,12 +1853,16 @@ open class Account: Service {
let callbackScheme = "appwrite-callback-\(client.config["project"] ?? "")"
_ = try await withCheckedThrowingContinuation { continuation in
WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in
continuation.resume(with: result)
/// main thread for PresentationContextProvider
DispatchQueue.main.async {
WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in
continuation.resume(with: result)
}
}
}
return true
}
///
+1 -1
View File
@@ -45,7 +45,7 @@ open class Locale: Service {
}
///
/// List Locale Codes
/// List locale codes
///
/// List of all locale codes in [ISO
/// 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).
+33
View File
@@ -7,11 +7,14 @@ open class Realtime : Service {
private let TYPE_ERROR = "error"
private let TYPE_EVENT = "event"
private let TYPE_PONG = "pong"
private let DEBOUNCE_NANOS = 1_000_000
private let HEARTBEAT_INTERVAL: UInt64 = 20_000_000_000 // 20 seconds in nanoseconds
private var socketClient: WebSocketClient? = nil
private var activeChannels = Set<String>()
private var activeSubscriptions = [Int: RealtimeCallback]()
private var heartbeatTask: Task<Void, Swift.Error>? = nil
let connectSync = DispatchQueue(label: "ConnectSync")
@@ -20,6 +23,29 @@ open class Realtime : Service {
private var subscriptionsCounter = 0
private var reconnect = true
private func startHeartbeat() {
stopHeartbeat()
heartbeatTask = Task {
do {
while !Task.isCancelled {
if let client = socketClient, client.isConnected {
client.send(text: #"{"type": "ping"}"#)
}
try await Task.sleep(nanoseconds: HEARTBEAT_INTERVAL)
}
} catch {
if !Task.isCancelled {
print("Heartbeat task failed: \(error.localizedDescription)")
}
}
}
}
private func stopHeartbeat() {
heartbeatTask?.cancel()
heartbeatTask = nil
}
private func createSocket() async throws {
guard activeChannels.count > 0 else {
reconnect = false
@@ -50,6 +76,8 @@ open class Realtime : Service {
}
private func closeSocket() async throws {
stopHeartbeat()
guard let client = socketClient,
let group = client.threadGroup else {
return
@@ -163,6 +191,7 @@ extension Realtime: WebSocketClientDelegate {
public func onOpen(channel: Channel) {
self.reconnectAttempts = 0
startHeartbeat()
}
public func onMessage(text: String) {
@@ -172,6 +201,7 @@ extension Realtime: WebSocketClientDelegate {
switch type {
case TYPE_ERROR: try! handleResponseError(from: json)
case TYPE_EVENT: handleResponseEvent(from: json)
case TYPE_PONG: break // Handle pong response if needed
default: break
}
}
@@ -179,6 +209,8 @@ extension Realtime: WebSocketClientDelegate {
}
public func onClose(channel: Channel, data: Data) async throws {
stopHeartbeat()
if (!reconnect) {
reconnect = true
return
@@ -196,6 +228,7 @@ extension Realtime: WebSocketClientDelegate {
}
public func onError(error: Swift.Error?, status: HTTPResponseStatus?) {
stopHeartbeat()
print(error?.localizedDescription ?? "Unknown error")
}
+1 -1
View File
@@ -200,7 +200,7 @@ open class Storage: Service {
}
///
/// Delete File
/// Delete file
///
/// Delete a file by its unique ID. Only users with write permissions have
/// access to delete this resource.
+4 -2
View File
@@ -286,7 +286,8 @@ open class Teams: Service {
/// List team memberships
///
/// Use this endpoint to list a team's members using the team's ID. All team
/// members have read access to this endpoint.
/// members have read access to this endpoint. Hide sensitive attributes from
/// the response by toggling membership privacy in the Console.
///
/// @param String teamId
/// @param [String] queries
@@ -401,7 +402,8 @@ open class Teams: Service {
/// Get team membership
///
/// Get a team member by the membership unique id. All team members have read
/// access for this resource.
/// access for this resource. Hide sensitive attributes from the response by
/// toggling membership privacy in the Console.
///
/// @param String teamId
/// @param String membershipId
@@ -1,13 +1,12 @@
import Foundation
public enum AuthenticationFactor: String, Codable {
public enum AuthenticationFactor: String, CustomStringConvertible {
case email = "email"
case phone = "phone"
case totp = "totp"
case recoverycode = "recoverycode"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
@@ -1,10 +1,9 @@
import Foundation
public enum AuthenticatorType: String, Codable {
public enum AuthenticatorType: String, CustomStringConvertible {
case totp = "totp"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
+3 -4
View File
@@ -1,6 +1,6 @@
import Foundation
public enum Browser: String, Codable {
public enum Browser: String, CustomStringConvertible {
case avantBrowser = "aa"
case androidWebViewBeta = "an"
case googleChrome = "ch"
@@ -16,8 +16,7 @@ public enum Browser: String, Codable {
case opera = "op"
case operaNext = "on"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
+3 -4
View File
@@ -1,6 +1,6 @@
import Foundation
public enum CreditCard: String, Codable {
public enum CreditCard: String, CustomStringConvertible {
case americanExpress = "amex"
case argencard = "argencard"
case cabal = "cabal"
@@ -18,8 +18,7 @@ public enum CreditCard: String, Codable {
case mIR = "mir"
case maestro = "maestro"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
+3 -4
View File
@@ -1,6 +1,6 @@
import Foundation
public enum ExecutionMethod: String, Codable {
public enum ExecutionMethod: String, CustomStringConvertible {
case gET = "GET"
case pOST = "POST"
case pUT = "PUT"
@@ -8,8 +8,7 @@ public enum ExecutionMethod: String, Codable {
case dELETE = "DELETE"
case oPTIONS = "OPTIONS"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
+3 -4
View File
@@ -1,6 +1,6 @@
import Foundation
public enum Flag: String, Codable {
public enum Flag: String, CustomStringConvertible {
case afghanistan = "af"
case angola = "ao"
case albania = "al"
@@ -197,8 +197,7 @@ public enum Flag: String, Codable {
case zambia = "zm"
case zimbabwe = "zw"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
+4 -4
View File
@@ -1,14 +1,14 @@
import Foundation
public enum ImageFormat: String, Codable {
public enum ImageFormat: String, CustomStringConvertible {
case jpg = "jpg"
case jpeg = "jpeg"
case gif = "gif"
case png = "png"
case webp = "webp"
case avif = "avif"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
+3 -4
View File
@@ -1,6 +1,6 @@
import Foundation
public enum ImageGravity: String, Codable {
public enum ImageGravity: String, CustomStringConvertible {
case center = "center"
case topLeft = "top-left"
case top = "top"
@@ -11,8 +11,7 @@ public enum ImageGravity: String, Codable {
case bottom = "bottom"
case bottomRight = "bottom-right"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
+3 -4
View File
@@ -1,6 +1,6 @@
import Foundation
public enum OAuthProvider: String, Codable {
public enum OAuthProvider: String, CustomStringConvertible {
case amazon = "amazon"
case apple = "apple"
case auth0 = "auth0"
@@ -41,8 +41,7 @@ public enum OAuthProvider: String, Codable {
case zoom = "zoom"
case mock = "mock"
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
public var description: String {
return rawValue
}
}
-4
View File
@@ -7,20 +7,16 @@ public class AlgoArgon2 {
/// Algo type.
public let type: String
/// Memory used to compute hash.
public let memoryCost: Int
/// Amount of time consumed to compute hash
public let timeCost: Int
/// Number of threads used to compute hash.
public let threads: Int
init(
type: String,
memoryCost: Int,
-1
View File
@@ -8,7 +8,6 @@ public class AlgoBcrypt {
public let type: String
init(
type: String
) {
-1
View File
@@ -8,7 +8,6 @@ public class AlgoMd5 {
public let type: String
init(
type: String
) {
-1
View File
@@ -8,7 +8,6 @@ public class AlgoPhpass {
public let type: String
init(
type: String
) {
-5
View File
@@ -7,24 +7,19 @@ public class AlgoScrypt {
/// Algo type.
public let type: String
/// CPU complexity of computed hash.
public let costCpu: Int
/// Memory complexity of computed hash.
public let costMemory: Int
/// Parallelization of computed hash.
public let costParallel: Int
/// Length used to compute hash.
public let length: Int
init(
type: String,
costCpu: Int,
@@ -7,20 +7,16 @@ public class AlgoScryptModified {
/// Algo type.
public let type: String
/// Salt used to compute hash.
public let salt: String
/// Separator used to compute hash.
public let saltSeparator: String
/// Key used to compute hash.
public let signerKey: String
init(
type: String,
salt: String,
-1
View File
@@ -8,7 +8,6 @@ public class AlgoSha {
public let type: String
init(
type: String
) {
-2
View File
@@ -7,12 +7,10 @@ public class Continent {
/// Continent name.
public let name: String
/// Continent two letter code.
public let code: String
init(
name: String,
code: String
@@ -7,12 +7,10 @@ public class ContinentList {
/// Total number of continents documents that matched your query.
public let total: Int
/// List of continents.
public let continents: [Continent]
init(
total: Int,
continents: [Continent]
-2
View File
@@ -7,12 +7,10 @@ public class Country {
/// Country name.
public let name: String
/// Country two-character ISO 3166-1 alpha code.
public let code: String
init(
name: String,
code: String
-2
View File
@@ -7,12 +7,10 @@ public class CountryList {
/// Total number of countries documents that matched your query.
public let total: Int
/// List of countries.
public let countries: [Country]
init(
total: Int,
countries: [Country]
-7
View File
@@ -7,32 +7,25 @@ public class Currency {
/// Currency symbol.
public let symbol: String
/// Currency name.
public let name: String
/// Currency native symbol.
public let symbolNative: String
/// Number of decimal digits.
public let decimalDigits: Int
/// Currency digit rounding.
public let rounding: Double
/// Currency code in [ISO 4217-1](http://en.wikipedia.org/wiki/ISO_4217) three-character format.
public let code: String
/// Currency plural name
public let namePlural: String
init(
symbol: String,
name: String,
@@ -7,12 +7,10 @@ public class CurrencyList {
/// Total number of currencies documents that matched your query.
public let total: Int
/// List of currencies.
public let currencies: [Currency]
init(
total: Int,
currencies: [Currency]
+3 -9
View File
@@ -7,26 +7,20 @@ public class Document<T : Codable> {
/// Document ID.
public let id: String
/// Collection ID.
public let collectionId: String
/// Database ID.
public let databaseId: String
/// Document creation date in ISO 8601 format.
public let createdAt: String
/// Document update date in ISO 8601 format.
public let updatedAt: String
/// Document permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).
public let permissions: [Any]
public let permissions: [String]
/// Additional properties
public let data: T
@@ -37,7 +31,7 @@ public class Document<T : Codable> {
databaseId: String,
createdAt: String,
updatedAt: String,
permissions: [Any],
permissions: [String],
data: T
) {
self.id = id
@@ -68,7 +62,7 @@ public class Document<T : Codable> {
databaseId: map["$databaseId"] as! String,
createdAt: map["$createdAt"] as! String,
updatedAt: map["$updatedAt"] as! String,
permissions: map["$permissions"] as! [Any],
permissions: map["$permissions"] as! [String],
data: try! JSONDecoder().decode(T.self, from: JSONSerialization.data(withJSONObject: map, options: []))
)
}
@@ -7,12 +7,10 @@ public class DocumentList<T : Codable> {
/// Total number of documents documents that matched your query.
public let total: Int
/// List of documents.
public let documents: [Document<T>]
init(
total: Int,
documents: [Document<T>]
+4 -21
View File
@@ -7,77 +7,60 @@ public class Execution {
/// Execution ID.
public let id: String
/// Execution creation date in ISO 8601 format.
public let createdAt: String
/// Execution upate date in ISO 8601 format.
public let updatedAt: String
/// Execution roles.
public let permissions: [Any]
public let permissions: [String]
/// Function ID.
public let functionId: String
/// The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.
public let trigger: String
/// The status of the function execution. Possible values can be: `waiting`, `processing`, `completed`, or `failed`.
public let status: String
/// HTTP request method type.
public let requestMethod: String
/// HTTP request path and query.
public let requestPath: String
/// HTTP response headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous.
public let requestHeaders: [Headers]
/// HTTP response status code.
public let responseStatusCode: Int
/// HTTP response body. This will return empty unless execution is created as synchronous.
public let responseBody: String
/// HTTP response headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous.
public let responseHeaders: [Headers]
/// Function logs. Includes the last 4,000 characters. This will return an empty string unless the response is returned using an API key or as part of a webhook payload.
public let logs: String
/// Function errors. Includes the last 4,000 characters. This will return an empty string unless the response is returned using an API key or as part of a webhook payload.
public let errors: String
/// Function execution duration in seconds.
public let duration: Double
/// The scheduled time for execution. If left empty, execution will be queued immediately.
public let scheduledAt: String?
init(
id: String,
createdAt: String,
updatedAt: String,
permissions: [Any],
permissions: [String],
functionId: String,
trigger: String,
status: String,
@@ -138,7 +121,7 @@ public class Execution {
id: map["$id"] as! String,
createdAt: map["$createdAt"] as! String,
updatedAt: map["$updatedAt"] as! String,
permissions: map["$permissions"] as! [Any],
permissions: map["$permissions"] as! [String],
functionId: map["functionId"] as! String,
trigger: map["trigger"] as! String,
status: map["status"] as! String,
@@ -151,7 +134,7 @@ public class Execution {
logs: map["logs"] as! String,
errors: map["errors"] as! String,
duration: map["duration"] as! Double,
scheduledAt: map["scheduledAt"] as? String?
scheduledAt: map["scheduledAt"] as? String
)
}
}
@@ -7,12 +7,10 @@ public class ExecutionList {
/// Total number of executions documents that matched your query.
public let total: Int
/// List of executions.
public let executions: [Execution]
init(
total: Int,
executions: [Execution]
+3 -14
View File
@@ -7,54 +7,43 @@ public class File {
/// File ID.
public let id: String
/// Bucket ID.
public let bucketId: String
/// File creation date in ISO 8601 format.
public let createdAt: String
/// File update date in ISO 8601 format.
public let updatedAt: String
/// File permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).
public let permissions: [Any]
public let permissions: [String]
/// File name.
public let name: String
/// File MD5 signature.
public let signature: String
/// File mime type.
public let mimeType: String
/// File original size in bytes.
public let sizeOriginal: Int
/// Total number of chunks available
public let chunksTotal: Int
/// Total number of chunks uploaded
public let chunksUploaded: Int
init(
id: String,
bucketId: String,
createdAt: String,
updatedAt: String,
permissions: [Any],
permissions: [String],
name: String,
signature: String,
mimeType: String,
@@ -97,7 +86,7 @@ public class File {
bucketId: map["bucketId"] as! String,
createdAt: map["$createdAt"] as! String,
updatedAt: map["$updatedAt"] as! String,
permissions: map["$permissions"] as! [Any],
permissions: map["$permissions"] as! [String],
name: map["name"] as! String,
signature: map["signature"] as! String,
mimeType: map["mimeType"] as! String,
-2
View File
@@ -7,12 +7,10 @@ public class FileList {
/// Total number of files documents that matched your query.
public let total: Int
/// List of files.
public let files: [File]
init(
total: Int,
files: [File]
-2
View File
@@ -7,12 +7,10 @@ public class Headers {
/// Header name.
public let name: String
/// Header value.
public let value: String
init(
name: String,
value: String
-10
View File
@@ -7,44 +7,34 @@ public class Identity {
/// Identity ID.
public let id: String
/// Identity creation date in ISO 8601 format.
public let createdAt: String
/// Identity update date in ISO 8601 format.
public let updatedAt: String
/// User ID.
public let userId: String
/// Identity Provider.
public let provider: String
/// ID of the User in the Identity Provider.
public let providerUid: String
/// Email of the User in the Identity Provider.
public let providerEmail: String
/// Identity Provider Access Token.
public let providerAccessToken: String
/// The date of when the access token expires in ISO 8601 format.
public let providerAccessTokenExpiry: String
/// Identity Provider Refresh Token.
public let providerRefreshToken: String
init(
id: String,
createdAt: String,
@@ -7,12 +7,10 @@ public class IdentityList {
/// Total number of identities documents that matched your query.
public let total: Int
/// List of identities.
public let identities: [Identity]
init(
total: Int,
identities: [Identity]
-1
View File
@@ -8,7 +8,6 @@ public class Jwt {
public let jwt: String
init(
jwt: String
) {
-3
View File
@@ -7,16 +7,13 @@ public class Language {
/// Language name.
public let name: String
/// Language two-character ISO 639-1 codes.
public let code: String
/// Language native name.
public let nativeName: String
init(
name: String,
code: String,
@@ -7,12 +7,10 @@ public class LanguageList {
/// Total number of languages documents that matched your query.
public let total: Int
/// List of languages.
public let languages: [Language]
init(
total: Int,
languages: [Language]
-7
View File
@@ -7,32 +7,25 @@ public class Locale {
/// User IP address.
public let ip: String
/// Country code in [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1) two-character format
public let countryCode: String
/// Country name. This field support localization.
public let country: String
/// Continent code. A two character continent code &quot;AF&quot; for Africa, &quot;AN&quot; for Antarctica, &quot;AS&quot; for Asia, &quot;EU&quot; for Europe, &quot;NA&quot; for North America, &quot;OC&quot; for Oceania, and &quot;SA&quot; for South America.
public let continentCode: String
/// Continent name. This field support localization.
public let continent: String
/// True if country is part of the European Union.
public let eu: Bool
/// Currency code in [ISO 4217-1](http://en.wikipedia.org/wiki/ISO_4217) three-character format
public let currency: String
init(
ip: String,
countryCode: String,
-2
View File
@@ -7,12 +7,10 @@ public class LocaleCode {
/// Locale codes in [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
public let code: String
/// Locale name
public let name: String
init(
code: String,
name: String
@@ -7,12 +7,10 @@ public class LocaleCodeList {
/// Total number of localeCodes documents that matched your query.
public let total: Int
/// List of localeCodes.
public let localeCodes: [LocaleCode]
init(
total: Int,
localeCodes: [LocaleCode]
-21
View File
@@ -7,88 +7,67 @@ public class Log {
/// Event name.
public let event: String
/// User ID.
public let userId: String
/// User Email.
public let userEmail: String
/// User Name.
public let userName: String
/// API mode when event triggered.
public let mode: String
/// IP session in use when the session was created.
public let ip: String
/// Log creation date in ISO 8601 format.
public let time: String
/// Operating system code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json).
public let osCode: String
/// Operating system name.
public let osName: String
/// Operating system version.
public let osVersion: String
/// Client type.
public let clientType: String
/// Client code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json).
public let clientCode: String
/// Client name.
public let clientName: String
/// Client version.
public let clientVersion: String
/// Client engine name.
public let clientEngine: String
/// Client engine name.
public let clientEngineVersion: String
/// Device name.
public let deviceName: String
/// Device brand name.
public let deviceBrand: String
/// Device model name.
public let deviceModel: String
/// Country two-character ISO 3166-1 alpha code.
public let countryCode: String
/// Country name.
public let countryName: String
init(
event: String,
userId: String,
-2
View File
@@ -7,12 +7,10 @@ public class LogList {
/// Total number of logs documents that matched your query.
public let total: Int
/// List of logs.
public let logs: [Log]
init(
total: Int,
logs: [Log]
+6 -19
View File
@@ -7,54 +7,41 @@ public class Membership {
/// Membership ID.
public let id: String
/// Membership creation date in ISO 8601 format.
public let createdAt: String
/// Membership update date in ISO 8601 format.
public let updatedAt: String
/// User ID.
public let userId: String
/// User name.
/// User name. Hide this attribute by toggling membership privacy in the Console.
public let userName: String
/// User email address.
/// User email address. Hide this attribute by toggling membership privacy in the Console.
public let userEmail: String
/// Team ID.
public let teamId: String
/// Team name.
public let teamName: String
/// Date, the user has been invited to join the team in ISO 8601 format.
public let invited: String
/// Date, the user has accepted the invitation to join the team in ISO 8601 format.
public let joined: String
/// User confirmation status, true if the user has joined the team or false otherwise.
public let confirm: Bool
/// Multi factor authentication status, true if the user has MFA enabled or false otherwise.
/// Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.
public let mfa: Bool
/// User list of roles
public let roles: [Any]
public let roles: [String]
init(
@@ -70,7 +57,7 @@ public class Membership {
joined: String,
confirm: Bool,
mfa: Bool,
roles: [Any]
roles: [String]
) {
self.id = id
self.createdAt = createdAt
@@ -119,7 +106,7 @@ public class Membership {
joined: map["joined"] as! String,
confirm: map["confirm"] as! Bool,
mfa: map["mfa"] as! Bool,
roles: map["roles"] as! [Any]
roles: map["roles"] as! [String]
)
}
}
@@ -7,12 +7,10 @@ public class MembershipList {
/// Total number of memberships documents that matched your query.
public let total: Int
/// List of memberships.
public let memberships: [Membership]
init(
total: Int,
memberships: [Membership]
@@ -7,20 +7,16 @@ public class MfaChallenge {
/// Token ID.
public let id: String
/// Token creation date in ISO 8601 format.
public let createdAt: String
/// User ID.
public let userId: String
/// Token expiration date in ISO 8601 format.
public let expire: String
init(
id: String,
createdAt: String,
-4
View File
@@ -7,20 +7,16 @@ public class MfaFactors {
/// Can TOTP be used for MFA challenge for this account.
public let totp: Bool
/// Can phone (SMS) be used for MFA challenge for this account.
public let phone: Bool
/// Can email be used for MFA challenge for this account.
public let email: Bool
/// Can recovery code be used for MFA challenge for this account.
public let recoveryCode: Bool
init(
totp: Bool,
phone: Bool,
@@ -5,12 +5,11 @@ import JSONCodable
public class MfaRecoveryCodes {
/// Recovery codes.
public let recoveryCodes: [Any]
public let recoveryCodes: [String]
init(
recoveryCodes: [Any]
recoveryCodes: [String]
) {
self.recoveryCodes = recoveryCodes
}
@@ -23,7 +22,7 @@ public class MfaRecoveryCodes {
public static func from(map: [String: Any] ) -> MfaRecoveryCodes {
return MfaRecoveryCodes(
recoveryCodes: map["recoveryCodes"] as! [Any]
recoveryCodes: map["recoveryCodes"] as! [String]
)
}
}
-2
View File
@@ -7,12 +7,10 @@ public class MfaType {
/// Secret token used for TOTP factor.
public let secret: String
/// URI for authenticator apps.
public let uri: String
init(
secret: String,
uri: String
-3
View File
@@ -7,16 +7,13 @@ public class Phone {
/// Phone code.
public let code: String
/// Country two-character ISO 3166-1 alpha code.
public let countryCode: String
/// Country name.
public let countryName: String
init(
code: String,
countryCode: String,
-2
View File
@@ -7,12 +7,10 @@ public class PhoneList {
/// Total number of phones documents that matched your query.
public let total: Int
/// List of phones.
public let phones: [Phone]
init(
total: Int,
phones: [Phone]
+3 -32
View File
@@ -7,120 +7,91 @@ public class Session {
/// Session ID.
public let id: String
/// Session creation date in ISO 8601 format.
public let createdAt: String
/// Session update date in ISO 8601 format.
public let updatedAt: String
/// User ID.
public let userId: String
/// Session expiration date in ISO 8601 format.
public let expire: String
/// Session Provider.
public let provider: String
/// Session Provider User ID.
public let providerUid: String
/// Session Provider Access Token.
public let providerAccessToken: String
/// The date of when the access token expires in ISO 8601 format.
public let providerAccessTokenExpiry: String
/// Session Provider Refresh Token.
public let providerRefreshToken: String
/// IP in use when the session was created.
public let ip: String
/// Operating system code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json).
public let osCode: String
/// Operating system name.
public let osName: String
/// Operating system version.
public let osVersion: String
/// Client type.
public let clientType: String
/// Client code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json).
public let clientCode: String
/// Client name.
public let clientName: String
/// Client version.
public let clientVersion: String
/// Client engine name.
public let clientEngine: String
/// Client engine name.
public let clientEngineVersion: String
/// Device name.
public let deviceName: String
/// Device brand name.
public let deviceBrand: String
/// Device model name.
public let deviceModel: String
/// Country two-character ISO 3166-1 alpha code.
public let countryCode: String
/// Country name.
public let countryName: String
/// Returns true if this the current user session.
public let current: Bool
/// Returns a list of active session factors.
public let factors: [Any]
public let factors: [String]
/// Secret used to authenticate the user. Only included if the request was made with an API key
public let secret: String
/// Most recent date in ISO 8601 format when the session successfully passed MFA challenge.
public let mfaUpdatedAt: String
init(
id: String,
createdAt: String,
@@ -148,7 +119,7 @@ public class Session {
countryCode: String,
countryName: String,
current: Bool,
factors: [Any],
factors: [String],
secret: String,
mfaUpdatedAt: String
) {
@@ -245,7 +216,7 @@ public class Session {
countryCode: map["countryCode"] as! String,
countryName: map["countryName"] as! String,
current: map["current"] as! Bool,
factors: map["factors"] as! [Any],
factors: map["factors"] as! [String],
secret: map["secret"] as! String,
mfaUpdatedAt: map["mfaUpdatedAt"] as! String
)
-2
View File
@@ -7,12 +7,10 @@ public class SessionList {
/// Total number of sessions documents that matched your query.
public let total: Int
/// List of sessions.
public let sessions: [Session]
init(
total: Int,
sessions: [Session]
-9
View File
@@ -7,40 +7,31 @@ public class Subscriber {
/// Subscriber ID.
public let id: String
/// Subscriber creation time in ISO 8601 format.
public let createdAt: String
/// Subscriber update date in ISO 8601 format.
public let updatedAt: String
/// Target ID.
public let targetId: String
/// Target.
public let target: Target
/// Topic ID.
public let userId: String
/// User Name.
public let userName: String
/// Topic ID.
public let topicId: String
/// The target provider type. Can be one of the following: `email`, `sms` or `push`.
public let providerType: String
init(
id: String,
createdAt: String,
+10 -11
View File
@@ -7,34 +7,29 @@ public class Target {
/// Target ID.
public let id: String
/// Target creation time in ISO 8601 format.
public let createdAt: String
/// Target update date in ISO 8601 format.
public let updatedAt: String
/// Target Name.
public let name: String
/// User ID.
public let userId: String
/// Provider ID.
public let providerId: String?
/// The target provider type. Can be one of the following: `email`, `sms` or `push`.
public let providerType: String
/// The target identifier.
public let identifier: String
/// Is the target expired.
public let expired: Bool
init(
@@ -45,7 +40,8 @@ public class Target {
userId: String,
providerId: String?,
providerType: String,
identifier: String
identifier: String,
expired: Bool
) {
self.id = id
self.createdAt = createdAt
@@ -55,6 +51,7 @@ public class Target {
self.providerId = providerId
self.providerType = providerType
self.identifier = identifier
self.expired = expired
}
public func toMap() -> [String: Any] {
@@ -66,7 +63,8 @@ public class Target {
"userId": userId as Any,
"providerId": providerId as Any,
"providerType": providerType as Any,
"identifier": identifier as Any
"identifier": identifier as Any,
"expired": expired as Any
]
}
@@ -77,9 +75,10 @@ public class Target {
updatedAt: map["$updatedAt"] as! String,
name: map["name"] as! String,
userId: map["userId"] as! String,
providerId: map["providerId"] as? String?,
providerId: map["providerId"] as? String,
providerType: map["providerType"] as! String,
identifier: map["identifier"] as! String
identifier: map["identifier"] as! String,
expired: map["expired"] as! Bool
)
}
}
-6
View File
@@ -7,28 +7,22 @@ public class Team<T : Codable> {
/// Team ID.
public let id: String
/// Team creation date in ISO 8601 format.
public let createdAt: String
/// Team update date in ISO 8601 format.
public let updatedAt: String
/// Team name.
public let name: String
/// Total number of team members.
public let total: Int
/// Team preferences as a key-value object
public let prefs: Preferences<T>
init(
id: String,
createdAt: String,
-2
View File
@@ -7,12 +7,10 @@ public class TeamList<T : Codable> {
/// Total number of teams documents that matched your query.
public let total: Int
/// List of teams.
public let teams: [Team<T>]
init(
total: Int,
teams: [Team<T>]
-6
View File
@@ -7,28 +7,22 @@ public class Token {
/// Token ID.
public let id: String
/// Token creation date in ISO 8601 format.
public let createdAt: String
/// User ID.
public let userId: String
/// Token secret key. This will return an empty string unless the response is returned using an API key or as part of a webhook payload.
public let secret: String
/// Token expiration date in ISO 8601 format.
public let expire: String
/// Security phrase of a token. Empty if security phrase was not requested when creating a token. It includes randomly generated phrase which is also sent in the external resource such as email.
public let phrase: String
init(
id: String,
createdAt: String,
+6 -25
View File
@@ -7,80 +7,61 @@ public class User<T : Codable> {
/// User ID.
public let id: String
/// User creation date in ISO 8601 format.
public let createdAt: String
/// User update date in ISO 8601 format.
public let updatedAt: String
/// User name.
public let name: String
/// Hashed user password.
public let password: String?
/// Password hashing algorithm.
public let hash: String?
/// Password hashing algorithm configuration.
public let hashOptions: Any?
/// User registration date in ISO 8601 format.
public let registration: String
/// User status. Pass `true` for enabled and `false` for disabled.
public let status: Bool
/// Labels for the user.
public let labels: [Any]
public let labels: [String]
/// Password update time in ISO 8601 format.
public let passwordUpdate: String
/// User email address.
public let email: String
/// User phone number in E.164 format.
public let phone: String
/// Email verification status.
public let emailVerification: Bool
/// Phone verification status.
public let phoneVerification: Bool
/// Multi factor authentication status.
public let mfa: Bool
/// User preferences as a key-value object
public let prefs: Preferences<T>
/// A user-owned message receiver. A single user may have multiple e.g. emails, phones, and a browser. Each target is registered with a single provider.
public let targets: [Target]
/// Most recent access date in ISO 8601 format. This attribute is only updated again after 24 hours.
public let accessedAt: String
init(
id: String,
createdAt: String,
@@ -91,7 +72,7 @@ public class User<T : Codable> {
hashOptions: Any?,
registration: String,
status: Bool,
labels: [Any],
labels: [String],
passwordUpdate: String,
email: String,
phone: String,
@@ -153,12 +134,12 @@ public class User<T : Codable> {
createdAt: map["$createdAt"] as! String,
updatedAt: map["$updatedAt"] as! String,
name: map["name"] as! String,
password: map["password"] as? String?,
hash: map["hash"] as? String?,
hashOptions: map["hashOptions"] as? Any?,
password: map["password"] as? String,
hash: map["hash"] as? String,
hashOptions: map["hashOptions"] as? Any,
registration: map["registration"] as! String,
status: map["status"] as! Bool,
labels: map["labels"] as! [Any],
labels: map["labels"] as! [String],
passwordUpdate: map["passwordUpdate"] as! String,
email: map["email"] as! String,
phone: map["phone"] as! String,
@@ -2,7 +2,7 @@ import UIKit
import NIO
import Appwrite
let host = "https://demo.appwrite.io/v1"
let host = "https://cloud.appwrite.io/v1"
class ViewController: UIViewController {
@@ -72,8 +72,8 @@ class ViewController: UIViewController {
do {
let response = try await account.createOAuth2Session(
provider: "facebook",
success: "https://demo.appwrite.io/auth/oauth2/success",
failure: "https://demo.appwrite.io/auth/oauth2/failure"
success: "https://cloud.appwrite.io/auth/oauth2/success",
failure: "https://cloud.appwrite.io/auth/oauth2/failure"
)
self.response = String(describing: response)
} catch {