diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a004e6..fa4d35e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -**CHANGELOG** \ No newline at end of file +# Change Log \ No newline at end of file diff --git a/LICENSE b/LICENSE index 4968768..d73a6e9 100644 --- a/LICENSE +++ b/LICENSE @@ -1 +1,12 @@ -test test test \ No newline at end of file +Copyright (c) 2021 Appwrite (https://appwrite.io) and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + + 3. Neither the name Appwrite nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Package.swift b/Package.swift index 4600405..f6d9692 100644 --- a/Package.swift +++ b/Package.swift @@ -7,19 +7,29 @@ let package = Package( products: [ .library( name: "Appwrite", - targets: ["Appwrite"] + targets: ["Appwrite", "AppwriteModels"] ), ], dependencies: [ .package(url: "https://github.com/swift-server/async-http-client.git", from: "1.0.0"), - .package(url: "https://github.com/abnegate/swockets.git", .branch("develop")) + .package(url: "https://github.com/apple/swift-nio.git", from: "2.32.0") ], targets: [ .target( name: "Appwrite", dependencies: [ .product(name: "AsyncHTTPClient", package: "async-http-client"), - "Swockets" + .product(name: "NIOWebSocket", package: "swift-nio"), + "AppwriteModels" + ] + ), + .target( + name: "AppwriteModels" + ), + .testTarget( + name: "AppwriteTests", + dependencies: [ + "Appwrite" ] ) ], diff --git a/README.md b/README.md index 86f1f01..b8417ad 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,18 @@ # Appwrite Apple SDK -![Swift Package Manager](https://img.shields.io/github/v/release/repoowner/reponame.svg?color=green&style=flat-square) -![License](https://img.shields.io/github/license/repoowner/reponame.svg?style=flat-square) -![Version](https://img.shields.io/badge/api%20version-0.8.0-blue.svg?style=flat-square) +![Cocoapods](https://img.shields.io/cocoapods/v/Appwrite.svg?color=green&style=flat-square) +![Swift Package Manager](https://img.shields.io/github/v/release/appwrite/sdk-for-apple.svg?color=green&style=flat-square) +![License](https://img.shields.io/github/license/appwrite/sdk-for-apple.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-0.11.0-blue.svg?style=flat-square) [![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) [![Twitter Account](https://img.shields.io/twitter/follow/appwrite_io?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite_io) [![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) -**WORK IN PROGRESS - NOT READY FOR USAGE** +**This SDK is compatible with Appwrite server version 0.11.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-apple/releases).** -![Appwrite](https://appwrite.io/v1/images/console.png) +Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Apple SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) + +![Appwrite](https://appwrite.io/images/github.png) ## Installation @@ -17,33 +20,47 @@ The Appwrite Swift SDK is available via multiple package managers, including Swift Package Manager. In order to use the Appwrite Swift SDK from Xcode, select File > Swift Packages > **Add Package Dependency** -In the dialog that appears, enter the Appwrite Swift SDK [package URL]() and click **Next**. +>>IMAGE<< + +In the dialog that appears, enter the Appwrite Swift SDK [package URL](git@github.com:appwrite/sdk-for-apple.git) and click **Next**. Once the repository information is loaded, add your version rules and click **Next** again. +>>IMAGE<< + On the final screen, make sure you see `Appwrite` as a product selected for your target: +>>IMAGE<< + ### Swift Package Manager Add the package to your `Package.swift` dependencies: ```swift dependencies: [ - .package(url: "https://github.com/appwrite/sdk-for-apple", from: "0.0.1"), + .package(url: "git@github.com:appwrite/sdk-for-apple.git", from: "0.1.0"), ], ``` Then add it to your target: ```swift - .target( - name: "YourAppTarget", - dependencies: [ - "Appwrite" - ] - ), + targets: [ + .target( + name: "YourAppTarget", + dependencies: [ + .product(name: "", package: "sdk-for-apple") + ] + ), ``` +### Cocoapods + +```ruby + pod '', git: 'git@github.com:appwrite/sdk-for-apple.git', tag: '0.1.0' +``` + + ## Contribution This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. diff --git a/Sources/Appwrite/Client.swift b/Sources/Appwrite/Client.swift index 0c52d24..dfad0a3 100644 --- a/Sources/Appwrite/Client.swift +++ b/Sources/Appwrite/Client.swift @@ -1,14 +1,10 @@ -// -// Client.swift -// -// Created by Armino -// GitHub: https://github.com/armino-dev/sdk-generator -// - import NIO +import NIOCore +import NIOFoundationCompat import NIOSSL import Foundation import AsyncHTTPClient +@_exported import AppwriteModels let DASHDASH = "--" let CRLF = "\r\n" @@ -22,9 +18,8 @@ open class Client { open var endPointRealtime: String? = nil open var headers: [String: String] = [ - "content-type": "", - "x-sdk-version": "appwrite:swiftclient:0.0.1", - "X-Appwrite-Response-Format": "0.7.0" + "content-type": "", + "x-sdk-version": "appwrite:swiftclient:0.1.0", "X-Appwrite-Response-Format": "0.10.0" ] open var config: [String: String] = [:] @@ -41,6 +36,10 @@ open class Client { public init() { http = Client.createHTTP() + + #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + addUserAgent() + #endif } private static func createHTTP( @@ -100,21 +99,6 @@ open class Client { return self } - /// - /// Set Key - /// - /// Your secret API key - /// - /// @param String value - /// - /// @return Client - /// - open func setKey(_ value: String) -> Client { - config["key"] = value - _ = addHeader(key: "X-Appwrite-Key", value: value) - return self - } - /// /// Set JWT /// @@ -143,19 +127,6 @@ open class Client { return self } - /// - /// Set Mode - /// - /// @param String value - /// - /// @return Client - /// - open func setMode(_ value: String) -> Client { - config["mode"] = value - _ = addHeader(key: "X-Appwrite-Mode", value: value) - return self - } - /// /// Set self signed @@ -164,7 +135,7 @@ open class Client { /// /// @return Client /// - open func setSelfSigned(_ status: Bool = false) -> Client { + open func setSelfSigned(_ status: Bool = true) -> Client { try! http.syncShutdown() http = Client.createHTTP(selfSigned: status) return self @@ -267,13 +238,23 @@ open class Client { /// @return Response /// @throws Exception /// - func call(method: String, path: String = "", headers: [String: String] = [:], params: [String: Any?] = [:], sink: ((ByteBuffer) -> Void)? = nil, completion: ((Result) -> Void)? = nil) { + open func call( + method: String, + path: String = "", + headers: [String: String] = [:], + params: [String: Any?] = [:], + sink: ((ByteBuffer) -> Void)? = nil, + convert: (([String: Any]) -> T)? = nil, + completion: ((Result) -> Void)? = nil + ) { self.headers.merge(headers) { (_, new) in new } - let queryParameters = method == "GET" && !params.isEmpty - ? "?" + parametersToQueryString(params: params) + let validParams = params.filter { $0.value != nil } + + let queryParameters = method == "GET" && !validParams.isEmpty + ? "?" + parametersToQueryString(params: validParams) : "" let targetURL = URL(string: endPoint + path + queryParameters)! @@ -290,42 +271,30 @@ open class Client { } addHeaders(to: &request) - addCookies(to: &request) - + request.addDomainCookies() if "GET" == method { - execute(request, completion: completion) + execute(request, convert: convert, completion: completion) return } do { - try buildBody(for: &request, with: params) + try buildBody(for: &request, with: validParams) } catch let error { completion?(Result.failure(AppwriteError(message: error.localizedDescription))) return } - execute(request, withSink: sink, completion: completion) + execute(request, withSink: sink, convert: convert, completion: completion) } - fileprivate func addHeaders(to request: inout HTTPClient.Request) { + private func addHeaders(to request: inout HTTPClient.Request) { for (key, value) in self.headers { request.headers.add(name: key, value: value) } } - fileprivate func addCookies(to request: inout HTTPClient.Request) { - let cookieJson = UserDefaults.standard.string(forKey: "\(request.url.host ?? "")-cookies") - let cookies = try! cookieJson?.fromJson(to: [HTTPClient.Cookie].self) - - if let authCookie = cookies?.first(where: { cookie in - cookie.name.starts(with: "a_session_") && !cookie.name.contains("legacy") - }) { - request.headers.add(name: "cookie", value: "\(authCookie.name)=\(authCookie.value)") - } - } - - fileprivate func buildBody( + private func buildBody( for request: inout HTTPClient.Request, with params: [String: Any?] ) throws { @@ -336,10 +305,11 @@ open class Client { } } - fileprivate func execute( + private func execute( _ request: HTTPClient.Request, withSink bufferSink: ((ByteBuffer) -> Void)? = nil, - completion: ((Result) -> Void)? = nil + convert: (([String: Any]) -> T)? = nil, + completion: ((Result) -> Void)? = nil ) { if bufferSink == nil { http.execute( @@ -358,23 +328,62 @@ open class Client { complete(with: result) } - func complete(with result: Result) { - if let completion = completion { - switch result { - case .failure(let error): print(error) - case .success(let response): - guard response.cookies.count > 0 else { - break + func complete(with result: Result) { + guard let completion = completion else { + return + } + + switch result { + case .failure(let error): print(error) + case .success(var response): + switch response.status.code { + case 0..<400: + if response.cookies.count > 0 { + UserDefaults.standard.set( + try! response.cookies.toJson(), + forKey: "\(response.host)-cookies" + ) + } + switch T.self { + case is Bool.Type: + completion(.success(true as! T)) + case is ByteBuffer.Type: + completion(.success(response.body! as! T)) + default: + if response.body == nil { + completion(.success(true as! T)) + return + } + let dict = try! JSONSerialization + .jsonObject(with: response.body!) as? [String: Any] + + completion(.success(convert?(dict!) ?? dict! as! T)) + } + default: + var message = "" + + do { + let dict = try JSONSerialization + .jsonObject(with: response.body!) as? [String: Any] + + message = dict?["message"] as? String + ?? response.status.reasonPhrase + } catch { + message = response.body!.readString(length: response.body!.readableBytes)! } - let cookieJson = try! response.cookies.toJson() - UserDefaults.standard.set(cookieJson, forKey: "\(response.host)-cookies") + + let error = AppwriteError( + message: message, + code: Int(response.status.code) + ) + + completion(.failure(error)) } - completion(result.mapError { AppwriteError(message: $0.localizedDescription) }) } } } - fileprivate func randomBoundary() -> String { + private func randomBoundary() -> String { var string = "" for _ in 0..<16 { string.append(Client.boundaryChars.randomElement()!) @@ -382,7 +391,7 @@ open class Client { return string } - fileprivate func buildJSON( + private func buildJSON( _ request: inout HTTPClient.Request, with params: [String: Any?] = [:] ) throws { @@ -391,7 +400,7 @@ open class Client { request.body = .data(json) } - fileprivate func buildMultipart( + private func buildMultipart( _ request: inout HTTPClient.Request, with params: [String: Any?] = [:] ) { @@ -447,6 +456,46 @@ open class Client { request.headers.add(name: "Content-Type", value: "multipart/form-data;boundary=\"\(boundary)\"") request.body = .byteBuffer(bodyBuffer) } + + private func addUserAgent() { + let packageInfo = OSPackageInfo.get() + let deviceInfo = OSDeviceInfo() + var device = ""; + var operatingSystem = "" + + #if os(iOS) + let iosinfo = deviceInfo.iOSInfo + device = "\(iosinfo!.modelIdentifier) iOS/\(iosinfo!.systemVersion)"; + operatingSystem = "ios" + #elseif os(tvOS) + let iosinfo = deviceInfo.iOSInfo + device = "\(iosinfo!.systemInfo.machine) tvOS/\(iosinfo!.systemVersion)"; + operatingSystem = "tvos" + #elseif os(watchOS) + let iosinfo = deviceInfo.iOSInfo + device = "\(iosinfo!.systemInfo.machine) watchOS/\(iosinfo!.systemVersion)"; + operatingSystem = "watchos" + #elseif os(macOS) + let macinfo = deviceInfo.macOSInfo + device = "(Macintosh; \(macinfo!.model))" + operatingSystem = "macos" + #elseif os(Linux) + let lininfo = deviceInfo.linuxInfo + device = "(Linux; U; \(lininfo!.id) \(lininfo!.version))" + operatingSystem = "linux" + #elseif os(Windows) + let wininfo = deviceInfo.windowsInfo + device = "(Windows NT; \(wininfo!.computerName))" + operatingSystem = "windows" + #endif + + #if !os(Linux) && !os(Windows) + _ = addHeader( + key: "user-agent", + value: "\(packageInfo.packageName)/\(packageInfo.version) \(device)" + ) + #endif + } } extension Client { diff --git a/Sources/Appwrite/DeviceInfo/Linux/LinuxDeviceInfo.swift b/Sources/Appwrite/DeviceInfo/Linux/LinuxDeviceInfo.swift new file mode 100644 index 0000000..cd29eae --- /dev/null +++ b/Sources/Appwrite/DeviceInfo/Linux/LinuxDeviceInfo.swift @@ -0,0 +1,100 @@ +#if os(Linux) +import Foundation + +class LinuxDeviceInfo : DeviceInfo { + + let name: String + let version: String + let id: String + let idLike: [String] + let versionCodename: String + let versionId: String + let prettyName: String + let buildId: String + let variant: String + let variantId: String + let machineId: String + + internal init( + name: String, + version: String, + id: String, + idLike: [String], + versionCodename: String, + versionId: String, + prettyName: String, + buildId: String, + variant: String, + variantId: String, + machineId: String + ) { + self.name = name + self.version = version + self.id = id + self.idLike = idLike + self.versionCodename = versionCodename + self.versionId = versionId + self.prettyName = prettyName + self.buildId = buildId + self.variant = variant + self.variantId = variantId + self.machineId = machineId + } + + public static func get() -> LinuxDeviceInfo { + let os = getOsRelease() + let lsb = getLsbRelease() + let machineId = getMachineId() + + return LinuxDeviceInfo( + name: os["NAME"] ?? "Linux", + version: os["VERSION"] ?? lsb["LSB_VERSION"] ?? "", + id: os["ID"] ?? lsb["DISTRIB_ID"] ?? "linux", + idLike: os["ID_LIKE"]?.split(separator: " ").map { String($0) } ?? [], + versionCodename: os["VERSION_CODENAME"] ?? lsb["DISTRIB_CODENAME"] ?? "", + versionId: os["VERSION_ID"] ?? lsb["DISTRIB_RELEASE"] ?? "", + prettyName: os["PRETTY_NAME"] ?? lsb["DISTRIB_DESCRIPTION"] ?? "Linux", + buildId: os["BUILD_ID"] ?? "", + variant: os["VARIANT"] ?? "", + variantId: os["VARIANT_ID"] ?? "", + machineId: machineId + ) + } + + private static func getOsRelease() -> [String: String] { + return tryReadKeyValues(path: "/etc/os-release") + } + + private static func getLsbRelease() -> [String: String] { + return tryReadKeyValues(path: "/etc/lsb-release") + } + + private static func getMachineId() -> String { + return tryReadValue(path: "/etc/machine-id")! + } + + private static func tryReadValue(path: String) -> String? { + let url = URL(fileURLWithPath: path) + return try! String(contentsOf: url, encoding: .utf8) + } + + private static func tryReadKeyValues(path: String) -> [String: String] { + let url = URL(fileURLWithPath: path) + let string = try! String(contentsOf: url, encoding: .utf8) + let lines = string.components(separatedBy: .newlines) + + var dict = [String: String]() + for line in lines { + let splits = line.split(separator: "=") + if splits.count > 1 { + let key = String(splits[0]) + let value = String(splits[1]) + + dict[key] = value + } + } + + return dict + } +} +#endif \ No newline at end of file diff --git a/Sources/Appwrite/DeviceInfo/MacOS/CwlSysCtl.swift b/Sources/Appwrite/DeviceInfo/MacOS/CwlSysCtl.swift new file mode 100644 index 0000000..55d1134 --- /dev/null +++ b/Sources/Appwrite/DeviceInfo/MacOS/CwlSysCtl.swift @@ -0,0 +1,171 @@ +// +// CwlSysctl.swift +// CwlUtils +// +// Created by Matt Gallagher on 2016/02/03. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if os(macOS) +import Foundation + +/// A "static"-only namespace around a series of functions that operate on buffers returned from the `Darwin.sysctl` function +public struct Sysctl { + /// Possible errors. + public enum Error: Swift.Error { + case unknown + case malformedUTF8 + case invalidSize + case posixError(POSIXErrorCode) + } + + /// Access the raw data for an array of sysctl identifiers. + public static func data(for keys: [Int32]) throws -> [Int8] { + return try keys.withUnsafeBufferPointer() { keysPointer throws -> [Int8] in + // Preflight the request to get the required data size + var requiredSize = 0 + let preFlightResult = Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), nil, &requiredSize, nil, 0) + if preFlightResult != 0 { + throw POSIXErrorCode(rawValue: errno).map { + print($0.rawValue) + return Error.posixError($0) + } ?? Error.unknown + } + + // Run the actual request with an appropriately sized array buffer + let data = Array(repeating: 0, count: requiredSize) + let result = data.withUnsafeBufferPointer() { dataBuffer -> Int32 in + return Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), UnsafeMutableRawPointer(mutating: dataBuffer.baseAddress), &requiredSize, nil, 0) + } + if result != 0 { + throw POSIXErrorCode(rawValue: errno).map { Error.posixError($0) } ?? Error.unknown + } + + return data + } + } + + /// Convert a sysctl name string like "hw.memsize" to the array of `sysctl` identifiers (e.g. [CTL_HW, HW_MEMSIZE]) + public static func keys(for name: String) throws -> [Int32] { + var keysBufferSize = Int(CTL_MAXNAME) + var keysBuffer = Array(repeating: 0, count: keysBufferSize) + try keysBuffer.withUnsafeMutableBufferPointer { (lbp: inout UnsafeMutableBufferPointer) throws in + try name.withCString { (nbp: UnsafePointer) throws in + guard sysctlnametomib(nbp, lbp.baseAddress, &keysBufferSize) == 0 else { + throw POSIXErrorCode(rawValue: errno).map { Error.posixError($0) } ?? Error.unknown + } + } + } + if keysBuffer.count > keysBufferSize { + keysBuffer.removeSubrange(keysBufferSize..(ofType: T.Type, forKeys keys: [Int32]) throws -> T { + let buffer = try data(for: keys) + if buffer.count != MemoryLayout.size { + throw Error.invalidSize + } + return try buffer.withUnsafeBufferPointer() { bufferPtr throws -> T in + guard let baseAddress = bufferPtr.baseAddress else { throw Error.unknown } + return baseAddress.withMemoryRebound(to: T.self, capacity: 1) { $0.pointee } + } + } + + /// Invoke `sysctl` with an array of identifers, interpreting the returned buffer as the specified type. This function will throw `Error.invalidSize` if the size of buffer returned from `sysctl` fails to match the size of `T`. + public static func value(ofType type: T.Type, forKeys keys: Int32...) throws -> T { + return try value(ofType: type, forKeys: keys) + } + + /// Invoke `sysctl` with the specified name, interpreting the returned buffer as the specified type. This function will throw `Error.invalidSize` if the size of buffer returned from `sysctl` fails to match the size of `T`. + public static func value(ofType type: T.Type, forName name: String) throws -> T { + return try value(ofType: type, forKeys: keys(for: name)) + } + + /// Invoke `sysctl` with an array of identifers, interpreting the returned buffer as a `String`. This function will throw `Error.malformedUTF8` if the buffer returned from `sysctl` cannot be interpreted as a UTF8 buffer. + public static func string(for keys: [Int32]) throws -> String { + let optionalString = try data(for: keys).withUnsafeBufferPointer() { dataPointer -> String? in + dataPointer.baseAddress.flatMap { String(validatingUTF8: $0) } + } + guard let s = optionalString else { + throw Error.malformedUTF8 + } + return s + } + + /// Invoke `sysctl` with an array of identifers, interpreting the returned buffer as a `String`. This function will throw `Error.malformedUTF8` if the buffer returned from `sysctl` cannot be interpreted as a UTF8 buffer. + public static func string(for keys: Int32...) throws -> String { + return try string(for: keys) + } + + /// Invoke `sysctl` with the specified name, interpreting the returned buffer as a `String`. This function will throw `Error.malformedUTF8` if the buffer returned from `sysctl` cannot be interpreted as a UTF8 buffer. + public static func string(for name: String) throws -> String { + return try string(for: keys(for: name)) + } + + /// e.g. "MyComputer.local" (from System Preferences -> Sharing -> Computer Name) or + /// "My-Name-iPhone" (from Settings -> General -> About -> Name) + public static var hostName: String { return try! Sysctl.string(for: [CTL_KERN, KERN_HOSTNAME]) } + + /// e.g. "x86_64" or "N71mAP" + /// NOTE: this is *corrected* on iOS devices to fetch hw.model + public static var machine: String { + #if os(iOS) && !arch(x86_64) && !arch(i386) + return try! Sysctl.string(for: [CTL_HW, HW_MODEL]) + #else + return try! Sysctl.string(for: [CTL_HW, HW_MACHINE]) + #endif + } + + /// e.g. "MacPro4,1" or "iPhone8,1" + /// NOTE: this is *corrected* on iOS devices to fetch hw.machine + public static var model: String { + #if os(iOS) && !arch(x86_64) && !arch(i386) + return try! Sysctl.string(for: [CTL_HW, HW_MACHINE]) + #else + return try! Sysctl.string(for: [CTL_HW, HW_MODEL]) + #endif + } + + /// e.g. "8" or "2" + public static var activeCPUs: Int32 { return try! Sysctl.value(ofType: Int32.self, forKeys: [CTL_HW, HW_AVAILCPU]) } + + /// e.g. "15.3.0" or "15.0.0" + public static var osRelease: String { return try! Sysctl.string(for: [CTL_KERN, KERN_OSRELEASE]) } + + /// e.g. "Darwin" or "Darwin" + public static var osType: String { return try! Sysctl.string(for: [CTL_KERN, KERN_OSTYPE]) } + + /// e.g. "15D21" or "13D20" + public static var osVersion: String { return try! Sysctl.string(for: [CTL_KERN, KERN_OSVERSION]) } + + /// e.g. "Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64" or + /// "Darwin Kernel Version 15.0.0: Wed Dec 9 22:19:38 PST 2015; root:xnu-3248.31.3~2/RELEASE_ARM64_S8000" + public static var version: String { return try! Sysctl.string(for: [CTL_KERN, KERN_VERSION]) } + + #if os(macOS) + /// e.g. 199506 (not available on iOS) + public static var osRev: Int32 { return try! Sysctl.value(ofType: Int32.self, forKeys: [CTL_KERN, KERN_OSREV]) } + + /// e.g. 2659000000 (not available on iOS) + public static var cpuFreq: Int64 { return try! Sysctl.value(ofType: Int64.self, forName: "hw.cpufrequency") } + + /// e.g. 25769803776 (not available on iOS) + public static var memSize: UInt64 { return try! Sysctl.value(ofType: UInt64.self, forKeys: [CTL_HW, HW_MEMSIZE]) } + #endif +} +#endif diff --git a/Sources/Appwrite/DeviceInfo/MacOS/MacOSDeviceInfo.swift b/Sources/Appwrite/DeviceInfo/MacOS/MacOSDeviceInfo.swift new file mode 100644 index 0000000..fe9610a --- /dev/null +++ b/Sources/Appwrite/DeviceInfo/MacOS/MacOSDeviceInfo.swift @@ -0,0 +1,17 @@ +#if os(macOS) +import Foundation + +class MacOSDeviceInfo : DeviceInfo { + let computerName = Sysctl.hostName + let hostName = Sysctl.osType + let arch = Sysctl.machine + let model = Sysctl.model + let kernelVersion = Sysctl.version + let osRelease = Sysctl.osRelease + let activeCPUs = Sysctl.activeCPUs + + public static func get() -> MacOSDeviceInfo { + return MacOSDeviceInfo() + } +} +#endif diff --git a/Sources/Appwrite/DeviceInfo/OSDeviceInfo.swift b/Sources/Appwrite/DeviceInfo/OSDeviceInfo.swift new file mode 100644 index 0000000..09509e1 --- /dev/null +++ b/Sources/Appwrite/DeviceInfo/OSDeviceInfo.swift @@ -0,0 +1,29 @@ +import Foundation + +protocol DeviceInfo {} + +class OSDeviceInfo { + + #if os(iOS) || os(watchOS) || os(tvOS) + var iOSInfo: iOSDeviceInfo? + #elseif os(macOS) + var macOSInfo: MacOSDeviceInfo? + #elseif os(Linux) + var linuxInfo: LinuxDeviceInfo? + #elseif os(Windows) + var windowsInfo: WindowsDeviceInfo? + #endif + + init() { + #if os(iOS) || os(watchOS) || os(tvOS) + self.iOSInfo = iOSDeviceInfo.get() + #elseif os(macOS) + self.macOSInfo = MacOSDeviceInfo.get() + #elseif os(Linux) + self.linuxInfo = LinuxDeviceInfo.get() + #elseif os(Windows) + self.windowsInfo = LinuxDeviceInfo.get() + #endif + } +} + diff --git a/Sources/Appwrite/DeviceInfo/Windows/WindowsDeviceInfo.swift b/Sources/Appwrite/DeviceInfo/Windows/WindowsDeviceInfo.swift new file mode 100644 index 0000000..d43b8a9 --- /dev/null +++ b/Sources/Appwrite/DeviceInfo/Windows/WindowsDeviceInfo.swift @@ -0,0 +1,31 @@ +#if os(Windows) +import Foundation + +class WindowsDeviceInfo : DeviceInfo { + + let numberOfCores: String + let computerName: String + let systemMemoryInMegabytes: UInt64 + + public init( + numberOfCores: String, + computerName: String, + systemMemoryInMegabytes: UInt64 + ) { + self.numberOfCores = numberOfCores + self.computerName = computerName + self.systemMemoryInMegabytes = systemMemoryInMegabytes + } + + public static func get() -> WindowsDeviceInfo { + let memory = ProcessInfo.processInfo.physicalMemory / 1000 / 1000 // Bytes to MB + + return WindowsDeviceInfo( + numberOfCores: ProcessInfo.processInfo.processorCount.description, + computerName: Host.current().localizedName ?? "", + systemMemoryInMegabytes: memory + ) + } +} +#endif + diff --git a/Sources/Appwrite/DeviceInfo/iOS/UIDevice+ModelName.swift b/Sources/Appwrite/DeviceInfo/iOS/UIDevice+ModelName.swift new file mode 100644 index 0000000..18c8e41 --- /dev/null +++ b/Sources/Appwrite/DeviceInfo/iOS/UIDevice+ModelName.swift @@ -0,0 +1,101 @@ +#if os(iOS) || os(tvOS) || os(watchOS) +import Foundation +import UIKit + +public extension UIDevice { + + static let modelName: String = { + var systemInfo = utsname() + uname(&systemInfo) + let machineMirror = Mirror(reflecting: systemInfo.machine) + let identifier = machineMirror.children.reduce("") { identifier, element in + guard let value = element.value as? Int8, value != 0 else { return identifier } + return identifier + String(UnicodeScalar(UInt8(value))) + } + + func mapToDevice(identifier: String) -> String { // swiftlint:disable:this cyclomatic_complexity + #if os(iOS) + switch identifier { + case "iPod5,1": return "iPod touch (5th generation)" + case "iPod7,1": return "iPod touch (6th generation)" + case "iPod9,1": return "iPod touch (7th generation)" + case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4" + case "iPhone4,1": return "iPhone 4s" + case "iPhone5,1", "iPhone5,2": return "iPhone 5" + case "iPhone5,3", "iPhone5,4": return "iPhone 5c" + case "iPhone6,1", "iPhone6,2": return "iPhone 5s" + case "iPhone7,2": return "iPhone 6" + case "iPhone7,1": return "iPhone 6 Plus" + case "iPhone8,1": return "iPhone 6s" + case "iPhone8,2": return "iPhone 6s Plus" + case "iPhone8,4": return "iPhone SE" + case "iPhone9,1", "iPhone9,3": return "iPhone 7" + case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus" + case "iPhone10,1", "iPhone10,4": return "iPhone 8" + case "iPhone10,2", "iPhone10,5": return "iPhone 8 Plus" + case "iPhone10,3", "iPhone10,6": return "iPhone X" + case "iPhone11,2": return "iPhone XS" + case "iPhone11,4", "iPhone11,6": return "iPhone XS Max" + case "iPhone11,8": return "iPhone XR" + case "iPhone12,1": return "iPhone 11" + case "iPhone12,3": return "iPhone 11 Pro" + case "iPhone12,5": return "iPhone 11 Pro Max" + case "iPhone12,8": return "iPhone SE (2nd generation)" + case "iPhone13,1": return "iPhone 12 mini" + case "iPhone13,2": return "iPhone 12" + case "iPhone13,3": return "iPhone 12 Pro" + case "iPhone13,4": return "iPhone 12 Pro Max" + case "iPhone14,4": return "iPhone 13 mini" + case "iPhone14,5": return "iPhone 13" + case "iPhone14,2": return "iPhone 13 Pro" + case "iPhone14,3": return "iPhone 13 Pro Max" + case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return "iPad 2" + case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad (3rd generation)" + case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad (4th generation)" + case "iPad6,11", "iPad6,12": return "iPad (5th generation)" + case "iPad7,5", "iPad7,6": return "iPad (6th generation)" + case "iPad7,11", "iPad7,12": return "iPad (7th generation)" + case "iPad11,6", "iPad11,7": return "iPad (8th generation)" + case "iPad12,1", "iPad12,2": return "iPad (9th generation)" + case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air" + case "iPad5,3", "iPad5,4": return "iPad Air 2" + case "iPad11,3", "iPad11,4": return "iPad Air (3rd generation)" + case "iPad13,1", "iPad13,2": return "iPad Air (4th generation)" + case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad mini" + case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad mini 2" + case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad mini 3" + case "iPad5,1", "iPad5,2": return "iPad mini 4" + case "iPad11,1", "iPad11,2": return "iPad mini (5th generation)" + case "iPad14,1", "iPad14,2": return "iPad mini (6th generation)" + case "iPad6,3", "iPad6,4": return "iPad Pro (9.7-inch)" + case "iPad7,3", "iPad7,4": return "iPad Pro (10.5-inch)" + case "iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4": return "iPad Pro (11-inch) (1st generation)" + case "iPad8,9", "iPad8,10": return "iPad Pro (11-inch) (2nd generation)" + case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7": return "iPad Pro (11-inch) (3rd generation)" + case "iPad6,7", "iPad6,8": return "iPad Pro (12.9-inch) (1st generation)" + case "iPad7,1", "iPad7,2": return "iPad Pro (12.9-inch) (2nd generation)" + case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8": return "iPad Pro (12.9-inch) (3rd generation)" + case "iPad8,11", "iPad8,12": return "iPad Pro (12.9-inch) (4th generation)" + case "iPad13,8", "iPad13,9", "iPad13,10", "iPad13,11":return "iPad Pro (12.9-inch) (5th generation)" + case "AppleTV5,3": return "Apple TV" + case "AppleTV6,2": return "Apple TV 4K" + case "AudioAccessory1,1": return "HomePod" + case "AudioAccessory5,1": return "HomePod mini" + case "i386", "x86_64": return "Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS"))" + default: return identifier + } + #elseif os(tvOS) + switch identifier { + case "AppleTV5,3": return "Apple TV 4" + case "AppleTV6,2": return "Apple TV 4K" + case "i386", "x86_64": return "Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "tvOS"))" + default: return identifier + } + #endif + } + + return mapToDevice(identifier: identifier) + }() + +} +#endif diff --git a/Sources/Appwrite/DeviceInfo/iOS/iOSDeviceInfo.swift b/Sources/Appwrite/DeviceInfo/iOS/iOSDeviceInfo.swift new file mode 100644 index 0000000..c091e8d --- /dev/null +++ b/Sources/Appwrite/DeviceInfo/iOS/iOSDeviceInfo.swift @@ -0,0 +1,47 @@ +#if os(iOS) || os(tvOS) || os(watchOS) +import Foundation +import UIKit + +class iOSDeviceInfo : DeviceInfo { + + let name: String + let systemName: String + let systemVersion: String + let model: String + let localizedModel: String + let identifierForVendor: String + let modelIdentifier: String + + internal init( + name: String, + systemName: String, + systemVersion: String, + model: String, + localizedModel: String, + identifierForVendor: String, + modelIdentifier: String + ) { + self.name = name + self.systemName = systemName + self.systemVersion = systemVersion + self.model = model + self.localizedModel = localizedModel + self.identifierForVendor = identifierForVendor + self.modelIdentifier = modelIdentifier + } + + public static func get() -> iOSDeviceInfo { + let device = UIDevice.current + + return iOSDeviceInfo( + name: device.name, + systemName: device.systemName, + systemVersion: device.systemVersion, + model: device.model, + localizedModel: device.localizedModel, + identifierForVendor: device.identifierForVendor?.uuidString ?? "", + modelIdentifier: UIDevice.modelName + ) + } +} +#endif diff --git a/Sources/Appwrite/Extensions/Codable+JSON.swift b/Sources/Appwrite/Extensions/Codable+JSON.swift index bfc037b..523eb83 100644 --- a/Sources/Appwrite/Extensions/Codable+JSON.swift +++ b/Sources/Appwrite/Extensions/Codable+JSON.swift @@ -1,7 +1,3 @@ -// -// Created by Jake Barnby on 13/09/21. -// - import Foundation let jsonEncoder = JSONEncoder() diff --git a/Sources/Appwrite/Extensions/Cookie+Codable.swift b/Sources/Appwrite/Extensions/Cookie+Codable.swift index 7dbc700..8f0d329 100644 --- a/Sources/Appwrite/Extensions/Cookie+Codable.swift +++ b/Sources/Appwrite/Extensions/Cookie+Codable.swift @@ -20,10 +20,9 @@ extension HTTPClient.Cookie : Codable { let values = try decoder.container(keyedBy: CodingKeys.self) name = try values.decode(String.self, forKey: .name) value = try values.decode(String.self, forKey: .value) - path = try values.decode(String.self, forKey: .path) - domain = try values.decode(String.self, forKey: .domain) - expires = try values.decode(Date.self, forKey: .expires) - value = try values.decode(String.self, forKey: .value) + path = try values.decodeIfPresent(String.self, forKey: .path) ?? "" + domain = try values.decodeIfPresent(String.self, forKey: .domain) ?? "" + expires = try values.decodeIfPresent(Date.self, forKey: .expires) ?? Date() maxAge = try values.decodeIfPresent(Int.self, forKey: .maxAge) ?? nil httpOnly = try values.decodeIfPresent(Bool.self, forKey: .httpOnly) ?? false secure = try values.decodeIfPresent(Bool.self, forKey: .secure) ?? false @@ -33,9 +32,9 @@ extension HTTPClient.Cookie : Codable { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(name, forKey: .name) try container.encode(value, forKey: .value) - try container.encode(path, forKey: .path) - try container.encode(domain, forKey: .domain) - try container.encode(expires, forKey: .expires) + try container.encodeIfPresent(path, forKey: .path) + try container.encodeIfPresent(domain, forKey: .domain) + try container.encodeIfPresent(expires, forKey: .expires) try container.encodeIfPresent(maxAge, forKey: .maxAge) try container.encodeIfPresent(httpOnly, forKey: .httpOnly) try container.encodeIfPresent(secure, forKey: .secure) diff --git a/Sources/Appwrite/Extensions/HTTPClientRequest+Cookies.swift b/Sources/Appwrite/Extensions/HTTPClientRequest+Cookies.swift new file mode 100644 index 0000000..fa01d3d --- /dev/null +++ b/Sources/Appwrite/Extensions/HTTPClientRequest+Cookies.swift @@ -0,0 +1,14 @@ +import AsyncHTTPClient +import Foundation + +extension HTTPClient.Request { + public mutating func addDomainCookies() { + let cookieJson = UserDefaults.standard.string(forKey: "\(url.host!)-cookies") + let cookies: [HTTPClient.Cookie?]? = try? cookieJson?.fromJson(to: [HTTPClient.Cookie].self) + ?? [(try? cookieJson?.fromJson(to: HTTPClient.Cookie.self))] + + if let authCookie = cookies?.first(where: { $0?.name.starts(with: "a_session_") == true } ) { + headers.add(name: "cookie", value: "\(authCookie!.name)=\(authCookie!.value)") + } + } +} \ No newline at end of file diff --git a/Sources/Appwrite/Models/AppwriteError.swift b/Sources/Appwrite/Models/AppwriteError.swift index 4d07982..5cb6653 100644 --- a/Sources/Appwrite/Models/AppwriteError.swift +++ b/Sources/Appwrite/Models/AppwriteError.swift @@ -3,8 +3,10 @@ import Foundation open class AppwriteError : Swift.Error, Decodable { public let message: String + public let code: Int? - init(message: String) { + init(message: String, code: Int? = nil) { self.message = message + self.code = code } } diff --git a/Sources/Appwrite/Models/File.swift b/Sources/Appwrite/Models/File.swift index 04d7c4a..46c355d 100644 --- a/Sources/Appwrite/Models/File.swift +++ b/Sources/Appwrite/Models/File.swift @@ -1,9 +1,3 @@ -// -// File.swift -// -// Created by Jake Barnby on 21/09/21. -// - import Foundation import NIO diff --git a/Sources/Appwrite/Models/RealtimeModels.swift b/Sources/Appwrite/Models/RealtimeModels.swift index 2010c7d..f80108c 100644 --- a/Sources/Appwrite/Models/RealtimeModels.swift +++ b/Sources/Appwrite/Models/RealtimeModels.swift @@ -1,7 +1,3 @@ -// -// Created by Jake Barnby on 13/09/21. -// - import Foundation public class RealtimeSubscription { @@ -12,43 +8,30 @@ public class RealtimeSubscription { } } -public class RealtimeCallback { - public let payloadType: T.Type - public let callback: (RealtimeResponseEvent) -> Void +public class RealtimeCallback { + public let channels: Set + public let callback: (RealtimeResponseEvent) -> Void init( - with payloadType: T.Type, - and callback: @escaping (RealtimeResponseEvent) -> Void + for channels: Set, + and callback: @escaping (RealtimeResponseEvent) -> Void ) { - self.payloadType = payloadType + self.channels = channels self.callback = callback } } -public class RealtimeResponse : Decodable { - public let type: String - public var data: Model - - init( - of type: String, - with data: Model - ) { - self.type = type - self.data = data - } -} - -public class RealtimeResponseEvent : Decodable { - public let event: String - public let channels: Array - public let timestamp: Int64 - public var payload: T +public class RealtimeResponseEvent { + public let event: String? + public let channels: [String]? + public let timestamp: Int64? + public var payload: [String: Any]? init( event: String, - channels: Array, + channels: [String], timestamp: Int64, - payload: T + payload: [String: Any] ) { self.event = event self.channels = channels @@ -56,10 +39,3 @@ public class RealtimeResponseEvent : Decodable { self.payload = payload } } - -enum RealtimeCode { - static let policyViolation = 1008 - static let unknown = -1 -} - -open class Model : Codable {} diff --git a/Sources/Appwrite/OAuth/View+OAuth.swift b/Sources/Appwrite/OAuth/View+OAuth.swift index 10d76d5..7d66863 100644 --- a/Sources/Appwrite/OAuth/View+OAuth.swift +++ b/Sources/Appwrite/OAuth/View+OAuth.swift @@ -1,32 +1,37 @@ +#if os(macOS) +typealias OSApplication = NSApplication +typealias OSViewController = NSViewController +let notificationType = NSApplication.willBecomeActiveNotification +#elseif os(iOS) || os(tvOS) || os(watchOS) +typealias OSApplication = UIApplication +typealias OSViewController = UIViewController +let notificationType = UIApplication.willEnterForegroundNotification +#endif + #if canImport(SwiftUI) import SwiftUI - @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension View { public func registerOAuthHandler() -> some View { onOpenURL { url in WebAuthComponent.handleIncomingCookie(from: url) - }.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in + }.onReceive(NotificationCenter.default.publisher(for: notificationType)) { _ in WebAuthComponent.onCallback() } } } #endif -#if canImport(UIKit) -@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *) -extension UIViewController { - public func registerOAuthHandler() { - self.addChild(UIHostingController(rootView: EmptyView().registerOAuthHandler())) - } -} - -#endif -#if canImport(AppKit) -@available(macOS 11.0, *) -extension NSViewController { +#if canImport(OSViewController) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) +extension OSViewController { public func registerOAuthHandler() { - self.addChild(NSHostingController(rootView: EmptyView().registerOAuthHandler())) + #if os(macOS) + typealias OSHostingController = NSHostingController + #elseif os(iOS) || os(tvOS) || os(watchOS) + typealias OSHostingController = UIHostingController + #endif + self.addChild(OSHostingController(rootView: EmptyView().registerOAuthHandler())) } } #endif diff --git a/Sources/Appwrite/PackageInfo/Apple/PackageInfo+Apple.swift b/Sources/Appwrite/PackageInfo/Apple/PackageInfo+Apple.swift new file mode 100644 index 0000000..2138da4 --- /dev/null +++ b/Sources/Appwrite/PackageInfo/Apple/PackageInfo+Apple.swift @@ -0,0 +1,23 @@ +import Foundation + +extension PackageInfo { + + public static func getApplePackage() -> PackageInfo { + let bundle = Bundle.main + + let appName = bundle.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String + ?? bundle.object(forInfoDictionaryKey: "CFBundleName") as? String + ?? "" + + let packageName = bundle.bundleIdentifier ?? "" + let version = bundle.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "" + let build = bundle.object(forInfoDictionaryKey: "CFBundleVersion") as? String ?? "" + + return PackageInfo( + appName: appName, + version: version, + buildNumber: build, + packageName: packageName + ) + } +} diff --git a/Sources/Appwrite/PackageInfo/Linux/PackageInfo+Linux.swift b/Sources/Appwrite/PackageInfo/Linux/PackageInfo+Linux.swift new file mode 100644 index 0000000..a12f7ed --- /dev/null +++ b/Sources/Appwrite/PackageInfo/Linux/PackageInfo+Linux.swift @@ -0,0 +1,24 @@ +import Foundation + +extension PackageInfo { + + public static func getLinuxPackage() -> PackageInfo { + let version = getVersionJson() + + return PackageInfo( + appName: version["app_name"] as! String, + version: version["version"] as! String, + buildNumber: version["build_number"] as! String, + packageName: "", + buildSignature: "" + ) + } + + private static func getVersionJson() -> [String: Any] { + let exePath = URL(fileURLWithPath: "/proc/self/exe").resolvingSymlinksInPath() + let appPath = exePath.deletingLastPathComponent() + let jsonPath = appPath.appendingPathComponent("version.json") + return try! JSONSerialization + .jsonObject(with: Data(contentsOf: jsonPath)) as! [String: Any] + } +} diff --git a/Sources/Appwrite/PackageInfo/OSPackageInfo.swift b/Sources/Appwrite/PackageInfo/OSPackageInfo.swift new file mode 100644 index 0000000..12d441f --- /dev/null +++ b/Sources/Appwrite/PackageInfo/OSPackageInfo.swift @@ -0,0 +1,14 @@ +import Foundation + +class OSPackageInfo { + + public static func get() -> PackageInfo { + #if os(iOS) || os(watchOS) || os(tvOS) || os(macOS) + return PackageInfo.getApplePackage() + #elseif os(Linux) + return PackageInfo.getLinuxPackage() + #elseif os(Windows) + return PackageInfo.getWindowsPackage() + #endif + } +} diff --git a/Sources/Appwrite/PackageInfo/PackageInfo.swift b/Sources/Appwrite/PackageInfo/PackageInfo.swift new file mode 100644 index 0000000..47e8d5a --- /dev/null +++ b/Sources/Appwrite/PackageInfo/PackageInfo.swift @@ -0,0 +1,24 @@ +import Foundation + +class PackageInfo { + + let appName: String + let version: String + let buildNumber: String + let packageName: String + let buildSignature: String? + + internal init( + appName: String, + version: String, + buildNumber: String, + packageName: String, + buildSignature: String? = nil + ) { + self.appName = appName + self.version = version + self.buildNumber = buildNumber + self.packageName = packageName + self.buildSignature = buildSignature + } +} diff --git a/Sources/Appwrite/PackageInfo/Windows/PackageInfo+Windows.swift b/Sources/Appwrite/PackageInfo/Windows/PackageInfo+Windows.swift new file mode 100644 index 0000000..2398f4f --- /dev/null +++ b/Sources/Appwrite/PackageInfo/Windows/PackageInfo+Windows.swift @@ -0,0 +1,13 @@ +import Foundation + +class WindowsPackageInfo : PackageInfo { + + public static func getWindowsPackage() -> PackageInfo { + return WindowsPackageInfo( + appName: "", + version: "", + buildNumber: "", + packageName: "" + ) + } +} diff --git a/Sources/Appwrite/Services/Account.swift b/Sources/Appwrite/Services/Account.swift index 764898a..e0512ff 100644 --- a/Sources/Appwrite/Services/Account.swift +++ b/Sources/Appwrite/Services/Account.swift @@ -1,6 +1,7 @@ import AsyncHTTPClient import Foundation import NIO +import AppwriteModels open class Account: Service { /// @@ -11,7 +12,9 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func get(completion: ((Result) -> Void)? = nil) { + open func get( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account" let params: [String: Any?] = [:] @@ -20,7 +23,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.User = { dict in + return AppwriteModels.User.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -39,7 +53,12 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func create(_ email: String, _ password: String, _ name: String = "", completion: ((Result) -> Void)? = nil) { + open func create( + email: String, + password: String, + name: String? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account" let params: [String: Any?] = [ @@ -52,7 +71,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.User = { dict in + return AppwriteModels.User.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -67,7 +97,9 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func delete(completion: ((Result) -> Void)? = nil) { + open func delete( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account" let params: [String: Any?] = [:] @@ -76,7 +108,13 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) + client.call( + method: "DELETE", + path: path, + headers: headers, + params: params, + completion: completion + ) } /// @@ -94,7 +132,11 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func updateEmail(_ email: String, _ password: String, completion: ((Result) -> Void)? = nil) { + open func updateEmail( + email: String, + password: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/email" let params: [String: Any?] = [ @@ -106,7 +148,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.User = { dict in + return AppwriteModels.User.from(map: dict) + } + + client.call( + method: "PATCH", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -115,12 +168,15 @@ open class Account: Service { /// Use this endpoint to create a JSON Web Token. You can use the resulting JWT /// to authenticate on behalf of the current user when working with the /// Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes - /// from its creation and will be invalid if the user will logout. + /// from its creation and will be invalid if the user will logout in that time + /// frame. /// /// @throws Exception /// @return array /// - open func createJWT(completion: ((Result) -> Void)? = nil) { + open func createJWT( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/jwt" let params: [String: Any?] = [:] @@ -129,7 +185,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Jwt = { dict in + return AppwriteModels.Jwt.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -141,7 +208,9 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func getLogs(completion: ((Result) -> Void)? = nil) { + open func getLogs( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/logs" let params: [String: Any?] = [:] @@ -150,7 +219,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.LogList = { dict in + return AppwriteModels.LogList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -162,7 +242,10 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func updateName(_ name: String, completion: ((Result) -> Void)? = nil) { + open func updateName( + name: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/name" let params: [String: Any?] = [ @@ -173,7 +256,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.User = { dict in + return AppwriteModels.User.from(map: dict) + } + + client.call( + method: "PATCH", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -188,7 +282,11 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func updatePassword(_ password: String, _ oldPassword: String = "", completion: ((Result) -> Void)? = nil) { + open func updatePassword( + password: String, + oldPassword: String? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/password" let params: [String: Any?] = [ @@ -200,7 +298,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.User = { dict in + return AppwriteModels.User.from(map: dict) + } + + client.call( + method: "PATCH", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -211,7 +320,9 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func getPrefs(completion: ((Result) -> Void)? = nil) { + open func getPrefs( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/prefs" let params: [String: Any?] = [:] @@ -220,7 +331,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Preferences = { dict in + return AppwriteModels.Preferences.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -229,11 +351,14 @@ open class Account: Service { /// Update currently logged in user account preferences. You can pass only the /// specific settings you wish to update. /// - /// @param Any? prefs + /// @param Any prefs /// @throws Exception /// @return array /// - open func updatePrefs(_ prefs: Any?, completion: ((Result) -> Void)? = nil) { + open func updatePrefs( + prefs: Any, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/prefs" let params: [String: Any?] = [ @@ -244,7 +369,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.User = { dict in + return AppwriteModels.User.from(map: dict) + } + + client.call( + method: "PATCH", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -264,7 +400,11 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func createRecovery(_ email: String, _ url: String, completion: ((Result) -> Void)? = nil) { + open func createRecovery( + email: String, + url: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/recovery" let params: [String: Any?] = [ @@ -276,11 +416,22 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Token = { dict in + return AppwriteModels.Token.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// - /// Complete Password Recovery + /// Create Password Recovery (confirmation) /// /// Use this endpoint to complete the user account password reset. Both the /// **userId** and **secret** arguments will be passed as query parameters to @@ -299,7 +450,13 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func updateRecovery(_ userId: String, _ secret: String, _ password: String, _ passwordAgain: String, completion: ((Result) -> Void)? = nil) { + open func updateRecovery( + userId: String, + secret: String, + password: String, + passwordAgain: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/recovery" let params: [String: Any?] = [ @@ -313,7 +470,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Token = { dict in + return AppwriteModels.Token.from(map: dict) + } + + client.call( + method: "PUT", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -325,7 +493,9 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func getSessions(completion: ((Result) -> Void)? = nil) { + open func getSessions( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/sessions" let params: [String: Any?] = [:] @@ -334,7 +504,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.SessionList = { dict in + return AppwriteModels.SessionList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -348,7 +529,11 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func createSession(_ email: String, _ password: String, completion: ((Result) -> Void)? = nil) { + open func createSession( + email: String, + password: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/sessions" let params: [String: Any?] = [ @@ -360,7 +545,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Session = { dict in + return AppwriteModels.Session.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -372,7 +568,9 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func deleteSessions(completion: ((Result) -> Void)? = nil) { + open func deleteSessions( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/sessions" let params: [String: Any?] = [:] @@ -381,7 +579,13 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) + client.call( + method: "DELETE", + path: path, + headers: headers, + params: params, + completion: completion + ) } /// @@ -389,14 +593,17 @@ open class Account: Service { /// /// Use this endpoint to allow a new user to register an anonymous account in /// your project. This route will also create a new session for the user. To - /// allow the new user to convert an anonymous account to a normal account - /// account, you need to update its [email and - /// password](/docs/client/account#accountUpdateEmail). + /// allow the new user to convert an anonymous account to a normal account, you + /// need to update its [email and + /// password](/docs/client/account#accountUpdateEmail) or create an [OAuth2 + /// session](/docs/client/account#accountCreateOAuth2Session). /// /// @throws Exception /// @return array /// - open func createAnonymousSession(completion: ((Result) -> Void)? = nil) { + open func createAnonymousSession( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/sessions/anonymous" let params: [String: Any?] = [:] @@ -405,7 +612,117 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Session = { dict in + return AppwriteModels.Session.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) + } + + /// + /// Create Magic URL session + /// + /// Sends the user an email with a secret key for creating a session. When the + /// user clicks the link in the email, the user is redirected back to the URL + /// you provided with the secret key and userId values attached to the URL + /// query string. Use the query string parameters to submit a request to the + /// [PUT + /// /account/sessions/magic-url](/docs/client/account#accountUpdateMagicURLSession) + /// endpoint to complete the login process. The link sent to the user's email + /// address is valid for 1 hour. If you are on a mobile device you can leave + /// the URL parameter empty, so that the login completion will be handled by + /// your Appwrite instance by default. + /// + /// @param String email + /// @param String url + /// @throws Exception + /// @return array + /// + open func createMagicURLSession( + email: String, + url: String? = nil, + completion: ((Result) -> Void)? = nil + ) { + let path: String = "/account/sessions/magic-url" + + let params: [String: Any?] = [ + "email": email, + "url": url + ] + + let headers: [String: String] = [ + "content-type": "application/json" + ] + + let convert: ([String: Any]) -> AppwriteModels.Token = { dict in + return AppwriteModels.Token.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) + } + + /// + /// Create Magic URL session (confirmation) + /// + /// Use this endpoint to complete creating the session with the Magic URL. Both + /// the **userId** and **secret** arguments will be passed as query parameters + /// to the redirect URL you have provided when sending your request to the + /// [POST + /// /account/sessions/magic-url](/docs/client/account#accountCreateMagicURLSession) + /// endpoint. + /// + /// Please note that in order to avoid a [Redirect + /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) + /// the only valid redirect URLs are the ones from domains you have set when + /// adding your platforms in the console interface. + /// + /// @param String userId + /// @param String secret + /// @throws Exception + /// @return array + /// + open func updateMagicURLSession( + userId: String, + secret: String, + completion: ((Result) -> Void)? = nil + ) { + let path: String = "/account/sessions/magic-url" + + let params: [String: Any?] = [ + "userId": userId, + "secret": secret + ] + + let headers: [String: String] = [ + "content-type": "application/json" + ] + + let convert: ([String: Any]) -> AppwriteModels.Session = { dict in + return AppwriteModels.Session.from(map: dict) + } + + client.call( + method: "PUT", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -415,22 +732,35 @@ open class Account: Service { /// choice. Each OAuth2 provider should be enabled from the Appwrite console /// first. Use the success and failure arguments to provide a redirect URL's /// back to your app when login is completed. + /// + /// If there is already an active session, the new session will be attached to + /// the logged-in account. If there are no active sessions, the server will + /// attempt to look for a user with the same email address as the email + /// received from the OAuth2 provider and attach the new session to the + /// existing user. If no matching user is found - the server will create a new + /// user.. + /// /// /// @param String provider /// @param String success /// @param String failure - /// @param Array? scopes + /// @param [Any] scopes /// @throws Exception /// @return array /// @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) - open func createOAuth2Session(_ provider: String, _ success: String = "https://appwrite.io/auth/oauth2/success", _ failure: String = "https://appwrite.io/auth/oauth2/failure", _ scopes: Array? = nil, completion: ((Result) -> Void)? = nil) { + open func createOAuth2Session( + provider: String, + success: String? = nil, + failure: String? = nil, + scopes: [Any]? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/account/sessions/oauth2/{provider}" path = path.replacingOccurrences( of: "{provider}", - with: provider - ) + with: provider ) let params: [String: Any?] = [ "success": success, @@ -451,6 +781,46 @@ open class Account: Service { } } + /// + /// Get Session By ID + /// + /// Use this endpoint to get a logged in user's session using a Session ID. + /// Inputting 'current' will return the current session being used. + /// + /// @param String sessionId + /// @throws Exception + /// @return array + /// + open func getSession( + sessionId: String, + completion: ((Result) -> Void)? = nil + ) { + var path: String = "/account/sessions/{sessionId}" + + path = path.replacingOccurrences( + of: "{sessionId}", + with: sessionId ) + + let params: [String: Any?] = [:] + + let headers: [String: String] = [ + "content-type": "application/json" + ] + + let convert: ([String: Any]) -> AppwriteModels.Session = { dict in + return AppwriteModels.Session.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) + } + /// /// Delete Account Session /// @@ -462,13 +832,15 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func deleteSession(_ sessionId: String, completion: ((Result) -> Void)? = nil) { + open func deleteSession( + sessionId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/account/sessions/{sessionId}" path = path.replacingOccurrences( of: "{sessionId}", - with: sessionId - ) + with: sessionId ) let params: [String: Any?] = [:] @@ -476,7 +848,13 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) + client.call( + method: "DELETE", + path: path, + headers: headers, + params: params, + completion: completion + ) } /// @@ -502,7 +880,10 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func createVerification(_ url: String, completion: ((Result) -> Void)? = nil) { + open func createVerification( + url: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/verification" let params: [String: Any?] = [ @@ -513,11 +894,22 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Token = { dict in + return AppwriteModels.Token.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// - /// Complete Email Verification + /// Create Email Verification (confirmation) /// /// Use this endpoint to complete the user email verification process. Use both /// the **userId** and **secret** parameters that were attached to your app URL @@ -529,7 +921,11 @@ open class Account: Service { /// @throws Exception /// @return array /// - open func updateVerification(_ userId: String, _ secret: String, completion: ((Result) -> Void)? = nil) { + open func updateVerification( + userId: String, + secret: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/account/verification" let params: [String: Any?] = [ @@ -541,7 +937,18 @@ open class Account: Service { "content-type": "application/json" ] - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Token = { dict in + return AppwriteModels.Token.from(map: dict) + } + + client.call( + method: "PUT", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } } diff --git a/Sources/Appwrite/Services/Avatars.swift b/Sources/Appwrite/Services/Avatars.swift index 95080f0..e46cb78 100644 --- a/Sources/Appwrite/Services/Avatars.swift +++ b/Sources/Appwrite/Services/Avatars.swift @@ -1,6 +1,7 @@ import AsyncHTTPClient import Foundation import NIO +import AppwriteModels open class Avatars: Service { /// @@ -18,13 +19,18 @@ open class Avatars: Service { /// @throws Exception /// @return array /// - open func getBrowser(_ code: String, _ width: Int = 100, _ height: Int = 100, _ quality: Int = 100, completion: ((Result) -> Void)? = nil) { + open func getBrowser( + code: String, + width: Int? = nil, + height: Int? = nil, + quality: Int? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/avatars/browsers/{code}" path = path.replacingOccurrences( of: "{code}", - with: code - ) + with: code ) let params: [String: Any?] = [ "width": width, @@ -33,7 +39,12 @@ open class Avatars: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -50,13 +61,18 @@ open class Avatars: Service { /// @throws Exception /// @return array /// - open func getCreditCard(_ code: String, _ width: Int = 100, _ height: Int = 100, _ quality: Int = 100, completion: ((Result) -> Void)? = nil) { + open func getCreditCard( + code: String, + width: Int? = nil, + height: Int? = nil, + quality: Int? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/avatars/credit-cards/{code}" path = path.replacingOccurrences( of: "{code}", - with: code - ) + with: code ) let params: [String: Any?] = [ "width": width, @@ -65,7 +81,12 @@ open class Avatars: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -79,7 +100,10 @@ open class Avatars: Service { /// @throws Exception /// @return array /// - open func getFavicon(_ url: String, completion: ((Result) -> Void)? = nil) { + open func getFavicon( + url: String, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/avatars/favicon" let params: [String: Any?] = [ @@ -87,7 +111,12 @@ open class Avatars: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -104,13 +133,18 @@ open class Avatars: Service { /// @throws Exception /// @return array /// - open func getFlag(_ code: String, _ width: Int = 100, _ height: Int = 100, _ quality: Int = 100, completion: ((Result) -> Void)? = nil) { + open func getFlag( + code: String, + width: Int? = nil, + height: Int? = nil, + quality: Int? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/avatars/flags/{code}" path = path.replacingOccurrences( of: "{code}", - with: code - ) + with: code ) let params: [String: Any?] = [ "width": width, @@ -119,7 +153,12 @@ open class Avatars: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -136,7 +175,12 @@ open class Avatars: Service { /// @throws Exception /// @return array /// - open func getImage(_ url: String, _ width: Int = 400, _ height: Int = 400, completion: ((Result) -> Void)? = nil) { + open func getImage( + url: String, + width: Int? = nil, + height: Int? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/avatars/image" let params: [String: Any?] = [ @@ -146,7 +190,12 @@ open class Avatars: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -171,7 +220,14 @@ open class Avatars: Service { /// @throws Exception /// @return array /// - open func getInitials(_ name: String = "", _ width: Int = 500, _ height: Int = 500, _ color: String = "", _ background: String = "", completion: ((Result) -> Void)? = nil) { + open func getInitials( + name: String? = nil, + width: Int? = nil, + height: Int? = nil, + color: String? = nil, + background: String? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/avatars/initials" let params: [String: Any?] = [ @@ -183,7 +239,12 @@ open class Avatars: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -199,7 +260,13 @@ open class Avatars: Service { /// @throws Exception /// @return array /// - open func getQR(_ text: String, _ size: Int = 400, _ margin: Int = 1, _ download: Bool = false, completion: ((Result) -> Void)? = nil) { + open func getQR( + text: String, + size: Int? = nil, + margin: Int? = nil, + download: Bool? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/avatars/qr" let params: [String: Any?] = [ @@ -210,7 +277,12 @@ open class Avatars: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } } diff --git a/Sources/Appwrite/Services/Database.swift b/Sources/Appwrite/Services/Database.swift index a6c5cd2..6daafcf 100644 --- a/Sources/Appwrite/Services/Database.swift +++ b/Sources/Appwrite/Services/Database.swift @@ -1,158 +1,9 @@ import AsyncHTTPClient import Foundation import NIO +import AppwriteModels open class Database: Service { - /// - /// List Collections - /// - /// Get a list of all the user collections. You can use the query params to - /// filter your results. On admin mode, this endpoint will return a list of all - /// of the project's collections. [Learn more about different API - /// modes](/docs/admin). - /// - /// @param String search - /// @param Int limit - /// @param Int offset - /// @param String orderType - /// @throws Exception - /// @return array - /// - open func listCollections(_ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { - let path: String = "/database/collections" - - let params: [String: Any?] = [ - "search": search, - "limit": limit, - "offset": offset, - "orderType": orderType - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Collection - /// - /// Create a new Collection. - /// - /// @param String name - /// @param Array? read - /// @param Array? write - /// @param Array? rules - /// @throws Exception - /// @return array - /// - open func createCollection(_ name: String, _ read: Array?, _ write: Array?, _ rules: Array?, completion: ((Result) -> Void)? = nil) { - let path: String = "/database/collections" - - let params: [String: Any?] = [ - "name": name, - "read": read, - "write": write, - "rules": rules - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Collection - /// - /// Get a collection by its unique ID. This endpoint response returns a JSON - /// object with the collection metadata. - /// - /// @param String collectionId - /// @throws Exception - /// @return array - /// - open func getCollection(_ collectionId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/database/collections/{collectionId}" - - path = path.replacingOccurrences( - of: "{collectionId}", - with: collectionId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Collection - /// - /// Update a collection by its unique ID. - /// - /// @param String collectionId - /// @param String name - /// @param Array? read - /// @param Array? write - /// @param Array? rules - /// @throws Exception - /// @return array - /// - open func updateCollection(_ collectionId: String, _ name: String, _ read: Array? = [], _ write: Array? = [], _ rules: Array? = nil, completion: ((Result) -> Void)? = nil) { - var path: String = "/database/collections/{collectionId}" - - path = path.replacingOccurrences( - of: "{collectionId}", - with: collectionId - ) - - let params: [String: Any?] = [ - "name": name, - "read": read, - "write": write, - "rules": rules - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Collection - /// - /// Delete a collection by its unique ID. Only users with write permissions - /// have access to delete this resource. - /// - /// @param String collectionId - /// @throws Exception - /// @return array - /// - open func deleteCollection(_ collectionId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/database/collections/{collectionId}" - - path = path.replacingOccurrences( - of: "{collectionId}", - with: collectionId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - /// /// List Documents /// @@ -162,7 +13,7 @@ open class Database: Service { /// modes](/docs/admin). /// /// @param String collectionId - /// @param Array? filters + /// @param [Any] filters /// @param Int limit /// @param Int offset /// @param String orderField @@ -172,13 +23,22 @@ open class Database: Service { /// @throws Exception /// @return array /// - open func listDocuments(_ collectionId: String, _ filters: Array? = nil, _ limit: Int = 25, _ offset: Int = 0, _ orderField: String = "", _ orderType: String = "ASC", _ orderCast: String = "string", _ search: String = "", completion: ((Result) -> Void)? = nil) { + open func listDocuments( + collectionId: String, + filters: [Any]? = nil, + limit: Int? = nil, + offset: Int? = nil, + orderField: String? = nil, + orderType: String? = nil, + orderCast: String? = nil, + search: String? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/database/collections/{collectionId}/documents" path = path.replacingOccurrences( of: "{collectionId}", - with: collectionId - ) + with: collectionId ) let params: [String: Any?] = [ "filters": filters, @@ -194,7 +54,18 @@ open class Database: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.DocumentList = { dict in + return AppwriteModels.DocumentList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -206,22 +77,30 @@ open class Database: Service { /// directly from your database console. /// /// @param String collectionId - /// @param Any? data - /// @param Array? read - /// @param Array? write + /// @param Any data + /// @param [Any] read + /// @param [Any] write /// @param String parentDocument /// @param String parentProperty /// @param String parentPropertyType /// @throws Exception /// @return array /// - open func createDocument(_ collectionId: String, _ data: Any?, _ read: Array? = [], _ write: Array? = [], _ parentDocument: String = "", _ parentProperty: String = "", _ parentPropertyType: String = "assign", completion: ((Result) -> Void)? = nil) { + open func createDocument( + collectionId: String, + data: Any, + read: [Any]? = nil, + write: [Any]? = nil, + parentDocument: String? = nil, + parentProperty: String? = nil, + parentPropertyType: String? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/database/collections/{collectionId}/documents" path = path.replacingOccurrences( of: "{collectionId}", - with: collectionId - ) + with: collectionId ) let params: [String: Any?] = [ "data": data, @@ -236,7 +115,18 @@ open class Database: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Document = { dict in + return AppwriteModels.Document.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -250,18 +140,20 @@ open class Database: Service { /// @throws Exception /// @return array /// - open func getDocument(_ collectionId: String, _ documentId: String, completion: ((Result) -> Void)? = nil) { + open func getDocument( + collectionId: String, + documentId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/database/collections/{collectionId}/documents/{documentId}" path = path.replacingOccurrences( of: "{collectionId}", - with: collectionId - ) + with: collectionId ) path = path.replacingOccurrences( of: "{documentId}", - with: documentId - ) + with: documentId ) let params: [String: Any?] = [:] @@ -269,7 +161,18 @@ open class Database: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Document = { dict in + return AppwriteModels.Document.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -280,24 +183,29 @@ open class Database: Service { /// /// @param String collectionId /// @param String documentId - /// @param Any? data - /// @param Array? read - /// @param Array? write + /// @param Any data + /// @param [Any] read + /// @param [Any] write /// @throws Exception /// @return array /// - open func updateDocument(_ collectionId: String, _ documentId: String, _ data: Any?, _ read: Array? = [], _ write: Array? = [], completion: ((Result) -> Void)? = nil) { + open func updateDocument( + collectionId: String, + documentId: String, + data: Any, + read: [Any]? = nil, + write: [Any]? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/database/collections/{collectionId}/documents/{documentId}" path = path.replacingOccurrences( of: "{collectionId}", - with: collectionId - ) + with: collectionId ) path = path.replacingOccurrences( of: "{documentId}", - with: documentId - ) + with: documentId ) let params: [String: Any?] = [ "data": data, @@ -309,7 +217,18 @@ open class Database: Service { "content-type": "application/json" ] - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Document = { dict in + return AppwriteModels.Document.from(map: dict) + } + + client.call( + method: "PATCH", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -324,18 +243,20 @@ open class Database: Service { /// @throws Exception /// @return array /// - open func deleteDocument(_ collectionId: String, _ documentId: String, completion: ((Result) -> Void)? = nil) { + open func deleteDocument( + collectionId: String, + documentId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/database/collections/{collectionId}/documents/{documentId}" path = path.replacingOccurrences( of: "{collectionId}", - with: collectionId - ) + with: collectionId ) path = path.replacingOccurrences( of: "{documentId}", - with: documentId - ) + with: documentId ) let params: [String: Any?] = [:] @@ -343,7 +264,13 @@ open class Database: Service { "content-type": "application/json" ] - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) + client.call( + method: "DELETE", + path: path, + headers: headers, + params: params, + completion: completion + ) } } diff --git a/Sources/Appwrite/Services/Functions.swift b/Sources/Appwrite/Services/Functions.swift index acdc33a..80247f6 100644 --- a/Sources/Appwrite/Services/Functions.swift +++ b/Sources/Appwrite/Services/Functions.swift @@ -1,166 +1,9 @@ import AsyncHTTPClient import Foundation import NIO +import AppwriteModels open class Functions: Service { - /// - /// List Functions - /// - /// Get a list of all the project's functions. You can use the query params to - /// filter your results. - /// - /// @param String search - /// @param Int limit - /// @param Int offset - /// @param String orderType - /// @throws Exception - /// @return array - /// - open func list(_ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { - let path: String = "/functions" - - let params: [String: Any?] = [ - "search": search, - "limit": limit, - "offset": offset, - "orderType": orderType - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Function - /// - /// Create a new function. You can pass a list of - /// [permissions](/docs/permissions) to allow different project users or team - /// with access to execute the function using the client API. - /// - /// @param String name - /// @param Array? execute - /// @param String env - /// @param Any? vars - /// @param Array? events - /// @param String schedule - /// @param Int timeout - /// @throws Exception - /// @return array - /// - open func create(_ name: String, _ execute: Array?, _ env: String, _ vars: Any? = nil, _ events: Array? = nil, _ schedule: String = "", _ timeout: Int = 15, completion: ((Result) -> Void)? = nil) { - let path: String = "/functions" - - let params: [String: Any?] = [ - "name": name, - "execute": execute, - "env": env, - "vars": vars, - "events": events, - "schedule": schedule, - "timeout": timeout - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Function - /// - /// Get a function by its unique ID. - /// - /// @param String functionId - /// @throws Exception - /// @return array - /// - open func get(_ functionId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Function - /// - /// Update function by its unique ID. - /// - /// @param String functionId - /// @param String name - /// @param Array? execute - /// @param Any? vars - /// @param Array? events - /// @param String schedule - /// @param Int timeout - /// @throws Exception - /// @return array - /// - open func update(_ functionId: String, _ name: String, _ execute: Array?, _ vars: Any? = nil, _ events: Array? = nil, _ schedule: String = "", _ timeout: Int = 15, completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - let params: [String: Any?] = [ - "name": name, - "execute": execute, - "vars": vars, - "events": events, - "schedule": schedule, - "timeout": timeout - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Function - /// - /// Delete a function by its unique ID. - /// - /// @param String functionId - /// @throws Exception - /// @return array - /// - open func delete(_ functionId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - /// /// List Executions /// @@ -177,13 +20,19 @@ open class Functions: Service { /// @throws Exception /// @return array /// - open func listExecutions(_ functionId: String, _ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { + open func listExecutions( + functionId: String, + search: String? = nil, + limit: Int? = nil, + offset: Int? = nil, + orderType: String? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/functions/{functionId}/executions" path = path.replacingOccurrences( of: "{functionId}", - with: functionId - ) + with: functionId ) let params: [String: Any?] = [ "search": search, @@ -196,7 +45,18 @@ open class Functions: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.ExecutionList = { dict in + return AppwriteModels.ExecutionList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -212,13 +72,16 @@ open class Functions: Service { /// @throws Exception /// @return array /// - open func createExecution(_ functionId: String, _ data: String = "", completion: ((Result) -> Void)? = nil) { + open func createExecution( + functionId: String, + data: String? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/functions/{functionId}/executions" path = path.replacingOccurrences( of: "{functionId}", - with: functionId - ) + with: functionId ) let params: [String: Any?] = [ "data": data @@ -228,7 +91,18 @@ open class Functions: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Execution = { dict in + return AppwriteModels.Execution.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -241,18 +115,20 @@ open class Functions: Service { /// @throws Exception /// @return array /// - open func getExecution(_ functionId: String, _ executionId: String, completion: ((Result) -> Void)? = nil) { + open func getExecution( + functionId: String, + executionId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/functions/{functionId}/executions/{executionId}" path = path.replacingOccurrences( of: "{functionId}", - with: functionId - ) + with: functionId ) path = path.replacingOccurrences( of: "{executionId}", - with: executionId - ) + with: executionId ) let params: [String: Any?] = [:] @@ -260,205 +136,18 @@ open class Functions: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } + let convert: ([String: Any]) -> AppwriteModels.Execution = { dict in + return AppwriteModels.Execution.from(map: dict) + } - /// - /// Update Function Tag - /// - /// Update the function code tag ID using the unique function ID. Use this - /// endpoint to switch the code tag that should be executed by the execution - /// endpoint. - /// - /// @param String functionId - /// @param String tag - /// @throws Exception - /// @return array - /// - open func updateTag(_ functionId: String, _ tag: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}/tag" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion ) - - let params: [String: Any?] = [ - "tag": tag - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// List Tags - /// - /// Get a list of all the project's code tags. You can use the query params to - /// filter your results. - /// - /// @param String functionId - /// @param String search - /// @param Int limit - /// @param Int offset - /// @param String orderType - /// @throws Exception - /// @return array - /// - open func listTags(_ functionId: String, _ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}/tags" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - let params: [String: Any?] = [ - "search": search, - "limit": limit, - "offset": offset, - "orderType": orderType - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Tag - /// - /// Create a new function code tag. Use this endpoint to upload a new version - /// of your code function. To execute your newly uploaded code, you'll need to - /// update the function's tag to use your new tag UID. - /// - /// This endpoint accepts a tar.gz file compressed with your code. Make sure to - /// include any dependencies your code has within the compressed file. You can - /// learn more about code packaging in the [Appwrite Cloud Functions - /// tutorial](/docs/functions). - /// - /// Use the "command" param to set the entry point used to execute your code. - /// - /// @param String functionId - /// @param String command - /// @param File code - /// @throws Exception - /// @return array - /// - open func createTag(_ functionId: String, _ command: String, _ code: File, completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}/tags" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - let params: [String: Any?] = [ - "command": command, - "code": code - ] - - let headers: [String: String] = [ - "content-type": "multipart/form-data" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Tag - /// - /// Get a code tag by its unique ID. - /// - /// @param String functionId - /// @param String tagId - /// @throws Exception - /// @return array - /// - open func getTag(_ functionId: String, _ tagId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}/tags/{tagId}" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - path = path.replacingOccurrences( - of: "{tagId}", - with: tagId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Tag - /// - /// Delete a code tag by its unique ID. - /// - /// @param String functionId - /// @param String tagId - /// @throws Exception - /// @return array - /// - open func deleteTag(_ functionId: String, _ tagId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}/tags/{tagId}" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - path = path.replacingOccurrences( - of: "{tagId}", - with: tagId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Function Usage - /// - /// @param String functionId - /// @param String range - /// @throws Exception - /// @return array - /// - open func getUsage(_ functionId: String, _ range: String = "30d", completion: ((Result) -> Void)? = nil) { - var path: String = "/functions/{functionId}/usage" - - path = path.replacingOccurrences( - of: "{functionId}", - with: functionId - ) - - let params: [String: Any?] = [ - "range": range - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) } } diff --git a/Sources/Appwrite/Services/Health.swift b/Sources/Appwrite/Services/Health.swift deleted file mode 100644 index 70d99e2..0000000 --- a/Sources/Appwrite/Services/Health.swift +++ /dev/null @@ -1,257 +0,0 @@ -import AsyncHTTPClient -import Foundation -import NIO - -open class Health: Service { - /// - /// Get HTTP - /// - /// Check the Appwrite HTTP server is up and responsive. - /// - /// @throws Exception - /// @return array - /// - open func get(completion: ((Result) -> Void)? = nil) { - let path: String = "/health" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Anti virus - /// - /// Check the Appwrite Anti Virus server is up and connection is successful. - /// - /// @throws Exception - /// @return array - /// - open func getAntiVirus(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/anti-virus" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Cache - /// - /// Check the Appwrite in-memory cache server is up and connection is - /// successful. - /// - /// @throws Exception - /// @return array - /// - open func getCache(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/cache" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get DB - /// - /// Check the Appwrite database server is up and connection is successful. - /// - /// @throws Exception - /// @return array - /// - open func getDB(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/db" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Certificate Queue - /// - /// Get the number of certificates that are waiting to be issued against - /// [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue - /// server. - /// - /// @throws Exception - /// @return array - /// - open func getQueueCertificates(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/queue/certificates" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Functions Queue - /// - /// @throws Exception - /// @return array - /// - open func getQueueFunctions(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/queue/functions" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Logs Queue - /// - /// Get the number of logs that are waiting to be processed in the Appwrite - /// internal queue server. - /// - /// @throws Exception - /// @return array - /// - open func getQueueLogs(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/queue/logs" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Tasks Queue - /// - /// Get the number of tasks that are waiting to be processed in the Appwrite - /// internal queue server. - /// - /// @throws Exception - /// @return array - /// - open func getQueueTasks(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/queue/tasks" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Usage Queue - /// - /// Get the number of usage stats that are waiting to be processed in the - /// Appwrite internal queue server. - /// - /// @throws Exception - /// @return array - /// - open func getQueueUsage(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/queue/usage" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Webhooks Queue - /// - /// Get the number of webhooks that are waiting to be processed in the Appwrite - /// internal queue server. - /// - /// @throws Exception - /// @return array - /// - open func getQueueWebhooks(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/queue/webhooks" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Local Storage - /// - /// Check the Appwrite local storage device is up and connection is successful. - /// - /// @throws Exception - /// @return array - /// - open func getStorageLocal(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/storage/local" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Time - /// - /// Check the Appwrite server time is synced with Google remote NTP server. We - /// use this technology to smoothly handle leap seconds with no disruptive - /// events. The [Network Time - /// Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is - /// used by hundreds of millions of computers and devices to synchronize their - /// clocks over the Internet. If your computer sets its own clock, it likely - /// uses NTP. - /// - /// @throws Exception - /// @return array - /// - open func getTime(completion: ((Result) -> Void)? = nil) { - let path: String = "/health/time" - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - -} diff --git a/Sources/Appwrite/Services/Locale.swift b/Sources/Appwrite/Services/Locale.swift index 7c2866a..925cc52 100644 --- a/Sources/Appwrite/Services/Locale.swift +++ b/Sources/Appwrite/Services/Locale.swift @@ -1,6 +1,7 @@ import AsyncHTTPClient import Foundation import NIO +import AppwriteModels open class Locale: Service { /// @@ -16,7 +17,9 @@ open class Locale: Service { /// @throws Exception /// @return array /// - open func get(completion: ((Result) -> Void)? = nil) { + open func get( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/locale" let params: [String: Any?] = [:] @@ -25,7 +28,18 @@ open class Locale: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Locale = { dict in + return AppwriteModels.Locale.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -37,7 +51,9 @@ open class Locale: Service { /// @throws Exception /// @return array /// - open func getContinents(completion: ((Result) -> Void)? = nil) { + open func getContinents( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/locale/continents" let params: [String: Any?] = [:] @@ -46,7 +62,18 @@ open class Locale: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.ContinentList = { dict in + return AppwriteModels.ContinentList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -58,7 +85,9 @@ open class Locale: Service { /// @throws Exception /// @return array /// - open func getCountries(completion: ((Result) -> Void)? = nil) { + open func getCountries( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/locale/countries" let params: [String: Any?] = [:] @@ -67,7 +96,18 @@ open class Locale: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.CountryList = { dict in + return AppwriteModels.CountryList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -79,7 +119,9 @@ open class Locale: Service { /// @throws Exception /// @return array /// - open func getCountriesEU(completion: ((Result) -> Void)? = nil) { + open func getCountriesEU( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/locale/countries/eu" let params: [String: Any?] = [:] @@ -88,7 +130,18 @@ open class Locale: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.CountryList = { dict in + return AppwriteModels.CountryList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -100,7 +153,9 @@ open class Locale: Service { /// @throws Exception /// @return array /// - open func getCountriesPhones(completion: ((Result) -> Void)? = nil) { + open func getCountriesPhones( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/locale/countries/phones" let params: [String: Any?] = [:] @@ -109,7 +164,18 @@ open class Locale: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.PhoneList = { dict in + return AppwriteModels.PhoneList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -122,7 +188,9 @@ open class Locale: Service { /// @throws Exception /// @return array /// - open func getCurrencies(completion: ((Result) -> Void)? = nil) { + open func getCurrencies( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/locale/currencies" let params: [String: Any?] = [:] @@ -131,7 +199,18 @@ open class Locale: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.CurrencyList = { dict in + return AppwriteModels.CurrencyList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -143,7 +222,9 @@ open class Locale: Service { /// @throws Exception /// @return array /// - open func getLanguages(completion: ((Result) -> Void)? = nil) { + open func getLanguages( + completion: ((Result) -> Void)? = nil + ) { let path: String = "/locale/languages" let params: [String: Any?] = [:] @@ -152,7 +233,18 @@ open class Locale: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.LanguageList = { dict in + return AppwriteModels.LanguageList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } } diff --git a/Sources/Appwrite/Services/Projects.swift b/Sources/Appwrite/Services/Projects.swift deleted file mode 100644 index 0abd796..0000000 --- a/Sources/Appwrite/Services/Projects.swift +++ /dev/null @@ -1,1075 +0,0 @@ -import AsyncHTTPClient -import Foundation -import NIO - -open class Projects: Service { - /// - /// List Projects - /// - /// @param String search - /// @param Int limit - /// @param Int offset - /// @param String orderType - /// @throws Exception - /// @return array - /// - open func list(_ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { - let path: String = "/projects" - - let params: [String: Any?] = [ - "search": search, - "limit": limit, - "offset": offset, - "orderType": orderType - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Project - /// - /// @param String name - /// @param String teamId - /// @param String description - /// @param String logo - /// @param String url - /// @param String legalName - /// @param String legalCountry - /// @param String legalState - /// @param String legalCity - /// @param String legalAddress - /// @param String legalTaxId - /// @throws Exception - /// @return array - /// - open func create(_ name: String, _ teamId: String, _ description: String = "", _ logo: String = "", _ url: String = "", _ legalName: String = "", _ legalCountry: String = "", _ legalState: String = "", _ legalCity: String = "", _ legalAddress: String = "", _ legalTaxId: String = "", completion: ((Result) -> Void)? = nil) { - let path: String = "/projects" - - let params: [String: Any?] = [ - "name": name, - "teamId": teamId, - "description": description, - "logo": logo, - "url": url, - "legalName": legalName, - "legalCountry": legalCountry, - "legalState": legalState, - "legalCity": legalCity, - "legalAddress": legalAddress, - "legalTaxId": legalTaxId - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Project - /// - /// @param String projectId - /// @throws Exception - /// @return array - /// - open func get(_ projectId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Project - /// - /// @param String projectId - /// @param String name - /// @param String description - /// @param String logo - /// @param String url - /// @param String legalName - /// @param String legalCountry - /// @param String legalState - /// @param String legalCity - /// @param String legalAddress - /// @param String legalTaxId - /// @throws Exception - /// @return array - /// - open func update(_ projectId: String, _ name: String, _ description: String = "", _ logo: String = "", _ url: String = "", _ legalName: String = "", _ legalCountry: String = "", _ legalState: String = "", _ legalCity: String = "", _ legalAddress: String = "", _ legalTaxId: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "name": name, - "description": description, - "logo": logo, - "url": url, - "legalName": legalName, - "legalCountry": legalCountry, - "legalState": legalState, - "legalCity": legalCity, - "legalAddress": legalAddress, - "legalTaxId": legalTaxId - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Project - /// - /// @param String projectId - /// @param String password - /// @throws Exception - /// @return array - /// - open func delete(_ projectId: String, _ password: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "password": password - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Project users limit - /// - /// @param String projectId - /// @param String limit - /// @throws Exception - /// @return array - /// - open func updateAuthLimit(_ projectId: String, _ limit: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/auth/limit" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "limit": limit - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Project auth method status. Use this endpoint to enable or disable a given auth method for this project. - /// - /// @param String projectId - /// @param String method - /// @param Bool status - /// @throws Exception - /// @return array - /// - open func updateAuthStatus(_ projectId: String, _ method: String, _ status: Bool, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/auth/{method}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{method}", - with: method - ) - - let params: [String: Any?] = [ - "status": status - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// List Domains - /// - /// @param String projectId - /// @throws Exception - /// @return array - /// - open func listDomains(_ projectId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/domains" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Domain - /// - /// @param String projectId - /// @param String domain - /// @throws Exception - /// @return array - /// - open func createDomain(_ projectId: String, _ domain: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/domains" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "domain": domain - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Domain - /// - /// @param String projectId - /// @param String domainId - /// @throws Exception - /// @return array - /// - open func getDomain(_ projectId: String, _ domainId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/domains/{domainId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{domainId}", - with: domainId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Domain - /// - /// @param String projectId - /// @param String domainId - /// @throws Exception - /// @return array - /// - open func deleteDomain(_ projectId: String, _ domainId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/domains/{domainId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{domainId}", - with: domainId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Domain Verification Status - /// - /// @param String projectId - /// @param String domainId - /// @throws Exception - /// @return array - /// - open func updateDomainVerification(_ projectId: String, _ domainId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/domains/{domainId}/verification" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{domainId}", - with: domainId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// List Keys - /// - /// @param String projectId - /// @throws Exception - /// @return array - /// - open func listKeys(_ projectId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/keys" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Key - /// - /// @param String projectId - /// @param String name - /// @param Array? scopes - /// @throws Exception - /// @return array - /// - open func createKey(_ projectId: String, _ name: String, _ scopes: Array?, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/keys" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "name": name, - "scopes": scopes - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Key - /// - /// @param String projectId - /// @param String keyId - /// @throws Exception - /// @return array - /// - open func getKey(_ projectId: String, _ keyId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/keys/{keyId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{keyId}", - with: keyId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Key - /// - /// @param String projectId - /// @param String keyId - /// @param String name - /// @param Array? scopes - /// @throws Exception - /// @return array - /// - open func updateKey(_ projectId: String, _ keyId: String, _ name: String, _ scopes: Array?, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/keys/{keyId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{keyId}", - with: keyId - ) - - let params: [String: Any?] = [ - "name": name, - "scopes": scopes - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Key - /// - /// @param String projectId - /// @param String keyId - /// @throws Exception - /// @return array - /// - open func deleteKey(_ projectId: String, _ keyId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/keys/{keyId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{keyId}", - with: keyId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Project OAuth2 - /// - /// @param String projectId - /// @param String provider - /// @param String appId - /// @param String secret - /// @throws Exception - /// @return array - /// - open func updateOAuth2(_ projectId: String, _ provider: String, _ appId: String = "", _ secret: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/oauth2" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "provider": provider, - "appId": appId, - "secret": secret - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// List Platforms - /// - /// @param String projectId - /// @throws Exception - /// @return array - /// - open func listPlatforms(_ projectId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/platforms" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Platform - /// - /// @param String projectId - /// @param String type - /// @param String name - /// @param String key - /// @param String store - /// @param String hostname - /// @throws Exception - /// @return array - /// - open func createPlatform(_ projectId: String, _ type: String, _ name: String, _ key: String = "", _ store: String = "", _ hostname: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/platforms" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "type": type, - "name": name, - "key": key, - "store": store, - "hostname": hostname - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Platform - /// - /// @param String projectId - /// @param String platformId - /// @throws Exception - /// @return array - /// - open func getPlatform(_ projectId: String, _ platformId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/platforms/{platformId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{platformId}", - with: platformId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Platform - /// - /// @param String projectId - /// @param String platformId - /// @param String name - /// @param String key - /// @param String store - /// @param String hostname - /// @throws Exception - /// @return array - /// - open func updatePlatform(_ projectId: String, _ platformId: String, _ name: String, _ key: String = "", _ store: String = "", _ hostname: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/platforms/{platformId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{platformId}", - with: platformId - ) - - let params: [String: Any?] = [ - "name": name, - "key": key, - "store": store, - "hostname": hostname - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Platform - /// - /// @param String projectId - /// @param String platformId - /// @throws Exception - /// @return array - /// - open func deletePlatform(_ projectId: String, _ platformId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/platforms/{platformId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{platformId}", - with: platformId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// List Tasks - /// - /// @param String projectId - /// @throws Exception - /// @return array - /// - open func listTasks(_ projectId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/tasks" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Task - /// - /// @param String projectId - /// @param String name - /// @param String status - /// @param String schedule - /// @param Bool security - /// @param String httpMethod - /// @param String httpUrl - /// @param Array? httpHeaders - /// @param String httpUser - /// @param String httpPass - /// @throws Exception - /// @return array - /// - open func createTask(_ projectId: String, _ name: String, _ status: String, _ schedule: String, _ security: Bool, _ httpMethod: String, _ httpUrl: String, _ httpHeaders: Array? = [], _ httpUser: String = "", _ httpPass: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/tasks" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "name": name, - "status": status, - "schedule": schedule, - "security": security, - "httpMethod": httpMethod, - "httpUrl": httpUrl, - "httpHeaders": httpHeaders, - "httpUser": httpUser, - "httpPass": httpPass - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Task - /// - /// @param String projectId - /// @param String taskId - /// @throws Exception - /// @return array - /// - open func getTask(_ projectId: String, _ taskId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/tasks/{taskId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{taskId}", - with: taskId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Task - /// - /// @param String projectId - /// @param String taskId - /// @param String name - /// @param String status - /// @param String schedule - /// @param Bool security - /// @param String httpMethod - /// @param String httpUrl - /// @param Array? httpHeaders - /// @param String httpUser - /// @param String httpPass - /// @throws Exception - /// @return array - /// - open func updateTask(_ projectId: String, _ taskId: String, _ name: String, _ status: String, _ schedule: String, _ security: Bool, _ httpMethod: String, _ httpUrl: String, _ httpHeaders: Array? = [], _ httpUser: String = "", _ httpPass: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/tasks/{taskId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{taskId}", - with: taskId - ) - - let params: [String: Any?] = [ - "name": name, - "status": status, - "schedule": schedule, - "security": security, - "httpMethod": httpMethod, - "httpUrl": httpUrl, - "httpHeaders": httpHeaders, - "httpUser": httpUser, - "httpPass": httpPass - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Task - /// - /// @param String projectId - /// @param String taskId - /// @throws Exception - /// @return array - /// - open func deleteTask(_ projectId: String, _ taskId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/tasks/{taskId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{taskId}", - with: taskId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Project - /// - /// @param String projectId - /// @param String range - /// @throws Exception - /// @return array - /// - open func getUsage(_ projectId: String, _ range: String = "30d", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/usage" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "range": range - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// List Webhooks - /// - /// @param String projectId - /// @throws Exception - /// @return array - /// - open func listWebhooks(_ projectId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/webhooks" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create Webhook - /// - /// @param String projectId - /// @param String name - /// @param Array? events - /// @param String url - /// @param Bool security - /// @param String httpUser - /// @param String httpPass - /// @throws Exception - /// @return array - /// - open func createWebhook(_ projectId: String, _ name: String, _ events: Array?, _ url: String, _ security: Bool, _ httpUser: String = "", _ httpPass: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/webhooks" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - let params: [String: Any?] = [ - "name": name, - "events": events, - "url": url, - "security": security, - "httpUser": httpUser, - "httpPass": httpPass - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get Webhook - /// - /// @param String projectId - /// @param String webhookId - /// @throws Exception - /// @return array - /// - open func getWebhook(_ projectId: String, _ webhookId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/webhooks/{webhookId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{webhookId}", - with: webhookId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update Webhook - /// - /// @param String projectId - /// @param String webhookId - /// @param String name - /// @param Array? events - /// @param String url - /// @param Bool security - /// @param String httpUser - /// @param String httpPass - /// @throws Exception - /// @return array - /// - open func updateWebhook(_ projectId: String, _ webhookId: String, _ name: String, _ events: Array?, _ url: String, _ security: Bool, _ httpUser: String = "", _ httpPass: String = "", completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/webhooks/{webhookId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{webhookId}", - with: webhookId - ) - - let params: [String: Any?] = [ - "name": name, - "events": events, - "url": url, - "security": security, - "httpUser": httpUser, - "httpPass": httpPass - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete Webhook - /// - /// @param String projectId - /// @param String webhookId - /// @throws Exception - /// @return array - /// - open func deleteWebhook(_ projectId: String, _ webhookId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/projects/{projectId}/webhooks/{webhookId}" - - path = path.replacingOccurrences( - of: "{projectId}", - with: projectId - ) - - path = path.replacingOccurrences( - of: "{webhookId}", - with: webhookId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - -} diff --git a/Sources/Appwrite/Services/Realtime.swift b/Sources/Appwrite/Services/Realtime.swift index d258d2a..495a2f1 100644 --- a/Sources/Appwrite/Services/Realtime.swift +++ b/Sources/Appwrite/Services/Realtime.swift @@ -1,9 +1,4 @@ -// -// Created by Jake Barnby on 13/09/21. -// - import Foundation -import Swockets import AsyncHTTPClient import NIO import NIOHTTP1 @@ -14,29 +9,37 @@ open class Realtime : Service { private let TYPE_EVENT = "event" private let DEBOUNCE_MILLIS = 1 - private var socketClient: SwocketClient? = nil - private var channelCallbacks = [String: NSMutableSet]() - private var errorCallbacks = [(AppwriteError) -> Void]() + private var socketClient: WebSocketClient? = nil + private var activeChannels = Set() + private var activeSubscriptions = [Int: RealtimeCallback]() let connectSync = DispatchQueue(label: "ConnectSync") let callbackSync = DispatchQueue(label: "CallbackSync") private var subCallDepth = 0 + private var reconnectAttempts = 0 + private var subscriptionsCounter = 0 + private var reconnect = true private func createSocket() { + guard activeChannels.count > 0 else { + return + } + var queryParams = "project=\(client.config["project"]!)" - for channel in channelCallbacks.keys { + for channel in activeChannels { queryParams += "&channels[]=\(channel)" } let url = "\(client.endPointRealtime!)/realtime?\(queryParams)" if (socketClient != nil) { + reconnect = false closeSocket() } - socketClient = SwocketClient(url, delegate: self)! + socketClient = WebSocketClient(url, delegate: self)! try! socketClient?.connect() } @@ -46,44 +49,70 @@ open class Realtime : Service { //socket?.close(RealtimeCode.POLICY_VIOLATION.value, null) } + private func getTimeout() -> Int { + switch reconnectAttempts { + case 0..<5: return 1000 + case 5..<15: return 5000 + case 15..<100: return 10000 + default: return 60000 + } + } + + public func subscribe( + channel: String, + callback: @escaping (RealtimeResponseEvent) -> Void + ) -> RealtimeSubscription { + return subscribe( + channels: [channel], + payloadType: String.self, + callback: callback + ) + } + public func subscribe( - channels: [String], - callback: @escaping (RealtimeResponseEvent) -> Void + channels: Set, + callback: @escaping (RealtimeResponseEvent) -> Void ) -> RealtimeSubscription { return subscribe( channels: channels, - payloadType: Model.self, + payloadType: String.self, callback: callback ) } - public func subscribe( - channels: [String], + public func subscribe( + channel: String, payloadType: T.Type, - callback: @escaping (RealtimeResponseEvent) -> Void + callback: @escaping (RealtimeResponseEvent) -> Void ) -> RealtimeSubscription { - for channel in channels { - if channelCallbacks[channel] == nil { - channelCallbacks[channel] = NSMutableSet() - channelCallbacks[channel]?.add(RealtimeCallback( - with: payloadType, - and: callback as (RealtimeResponseEvent) -> Void - )) - continue - } - channelCallbacks[channel]?.add(RealtimeCallback( - with: payloadType, - and: callback as (RealtimeResponseEvent) -> Void - )) + return subscribe( + channels: [channel], + payloadType: T.self, + callback: callback + ) + } + + public func subscribe( + channels: Set, + payloadType: T.Type, + callback: @escaping (RealtimeResponseEvent) -> Void + ) -> RealtimeSubscription { + subscriptionsCounter += 1 + let counter = subscriptionsCounter + + channels.forEach { + activeChannels.insert($0) } + activeSubscriptions[counter] = RealtimeCallback( + for: Set(channels), + and: callback + ) + connectSync.sync { subCallDepth+=1 } - let group = DispatchGroup() - - group.enter() DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(DEBOUNCE_MILLIS)) { if (self.subCallDepth == 1) { self.createSocket() @@ -91,81 +120,96 @@ open class Realtime : Service { self.connectSync.sync { self.subCallDepth-=1 } - group.leave() } - group.wait() return RealtimeSubscription { - self.unsubscribe(channels: channels) + self.activeSubscriptions[counter] = nil + self.cleanUp(channels: channels) + self.createSocket() } } - func unsubscribe(channels: [String]) { - for channel in channels { - channelCallbacks[channel] = NSMutableSet() - } - if (channelCallbacks.allSatisfy { $0.value.count != 0 }) { - errorCallbacks = [] - closeSocket() + func cleanUp(channels: Set) { + activeChannels = activeChannels.filter { channel in + guard channels.contains(channel) else { + return true + } + let subsWithChannel = activeSubscriptions.filter { callback in + return callback.value.channels.contains(channel) + } + return subsWithChannel.isEmpty } } - - func doOnError(callback: @escaping (AppwriteError) -> Void) { - errorCallbacks.append(callback) - } } -extension Realtime: SwocketClientDelegate { +extension Realtime: WebSocketClientDelegate { - public func onMessage(text: String) { - let message = try! text.fromJson(to: RealtimeResponse.self) - switch message.type { - case TYPE_ERROR: handleResponseError(from: message) - case TYPE_EVENT: handleResponseEvent(from: message) - default: break - } + public func onOpen(channel: Channel) { + self.reconnectAttempts = 0 } - public func onMessage(data: Data) { + public func onMessage(text: String) { + let data = Data(text.utf8) + if let json = try! JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { + if let type = json["type"] as? String { + switch type { + case TYPE_ERROR: try! handleResponseError(from: json) + case TYPE_EVENT: handleResponseEvent(from: json) + default: break + } + } + } } public func onClose(channel: Channel, data: Data) { -// if (code == RealtimeCode.POLICY_VIOLATION.value) { -// return -// } - DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) { - self.createSocket() + if (!reconnect) { + reconnect = true + return } - } - public func onError(error: Error?, status: HTTPResponseStatus?) { - print(error!) - } + let timeout = getTimeout() - func handleResponseError(from message: RealtimeResponse) { - let error = try! message.data - .toJson() - .fromJson(to: AppwriteError.self) + print("Realtime disconnected. Re-connecting in \(timeout / 1000) seconds.") - for callback in errorCallbacks { - callback(error) + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(timeout)) { + self.reconnectAttempts += 1 + self.createSocket() } } - func handleResponseEvent(from message: RealtimeResponse) { - let event = try! message.data - .toJson() - .fromJson(to: RealtimeResponseEvent.self) + public func onError(error: Swift.Error?, status: HTTPResponseStatus?) { + print(error?.localizedDescription ?? "Unknown error") + } - for channel in event.channels { - for callback in channelCallbacks[channel]! { - let typedCallback = (callback as! RealtimeCallback) + func handleResponseError(from json: [String: Any]) throws { + throw AppwriteError(message: json["message"] as? String ?? "Unknown error") + } - event.payload = try! event.payload - .toJson() - .fromJson(to: typedCallback.payloadType) + func handleResponseEvent(from json: [String: Any]) { + guard let data = json["data"] as? [String: Any] else { + return + } + guard let channels = data["channels"] as? Array else { + return + } + guard let payload = data["payload"] as? [String: Any] else { + return + } + guard channels.contains(where: { channel in + activeChannels.contains(channel) + }) else { + return + } - typedCallback.callback(event) + for subscription in activeSubscriptions { + if channels.contains(where: { subscription.value.channels.contains($0) }) { + let response = RealtimeResponseEvent( + event: data["event"] as! String, + channels: channels, + timestamp: data["timestamp"] as! Int64, + payload: payload + ) + subscription.value.callback(response) } } } diff --git a/Sources/Appwrite/Services/Service.swift b/Sources/Appwrite/Services/Service.swift index 146190e..3cf3d97 100644 --- a/Sources/Appwrite/Services/Service.swift +++ b/Sources/Appwrite/Services/Service.swift @@ -1,15 +1,8 @@ -// -// Service.swift -// -// Created by Armino -// GitHub: https://github.com/armino-dev/sdk-generator -// - open class Service { internal var client: Client - public init(client: Client) + public init(_ client: Client) { self.client = client } diff --git a/Sources/Appwrite/Services/Storage.swift b/Sources/Appwrite/Services/Storage.swift index c84e7d8..af16305 100644 --- a/Sources/Appwrite/Services/Storage.swift +++ b/Sources/Appwrite/Services/Storage.swift @@ -1,6 +1,7 @@ import AsyncHTTPClient import Foundation import NIO +import AppwriteModels open class Storage: Service { /// @@ -17,7 +18,13 @@ open class Storage: Service { /// @throws Exception /// @return array /// - open func listFiles(_ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { + open func listFiles( + search: String? = nil, + limit: Int? = nil, + offset: Int? = nil, + orderType: String? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/storage/files" let params: [String: Any?] = [ @@ -31,7 +38,18 @@ open class Storage: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.FileList = { dict in + return AppwriteModels.FileList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -42,12 +60,17 @@ open class Storage: Service { /// read and write arguments. /// /// @param File file - /// @param Array? read - /// @param Array? write + /// @param [Any] read + /// @param [Any] write /// @throws Exception /// @return array /// - open func createFile(_ file: File, _ read: Array? = [], _ write: Array? = [], completion: ((Result) -> Void)? = nil) { + open func createFile( + file: File, + read: [Any]? = nil, + write: [Any]? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/storage/files" let params: [String: Any?] = [ @@ -60,7 +83,18 @@ open class Storage: Service { "content-type": "multipart/form-data" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.File = { dict in + return AppwriteModels.File.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -73,13 +107,15 @@ open class Storage: Service { /// @throws Exception /// @return array /// - open func getFile(_ fileId: String, completion: ((Result) -> Void)? = nil) { + open func getFile( + fileId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/storage/files/{fileId}" path = path.replacingOccurrences( of: "{fileId}", - with: fileId - ) + with: fileId ) let params: [String: Any?] = [:] @@ -87,7 +123,18 @@ open class Storage: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.File = { dict in + return AppwriteModels.File.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -97,18 +144,22 @@ open class Storage: Service { /// access to update this resource. /// /// @param String fileId - /// @param Array? read - /// @param Array? write + /// @param [Any] read + /// @param [Any] write /// @throws Exception /// @return array /// - open func updateFile(_ fileId: String, _ read: Array?, _ write: Array?, completion: ((Result) -> Void)? = nil) { + open func updateFile( + fileId: String, + read: [Any], + write: [Any], + completion: ((Result) -> Void)? = nil + ) { var path: String = "/storage/files/{fileId}" path = path.replacingOccurrences( of: "{fileId}", - with: fileId - ) + with: fileId ) let params: [String: Any?] = [ "read": read, @@ -119,7 +170,18 @@ open class Storage: Service { "content-type": "application/json" ] - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.File = { dict in + return AppwriteModels.File.from(map: dict) + } + + client.call( + method: "PUT", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -132,13 +194,15 @@ open class Storage: Service { /// @throws Exception /// @return array /// - open func deleteFile(_ fileId: String, completion: ((Result) -> Void)? = nil) { + open func deleteFile( + fileId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/storage/files/{fileId}" path = path.replacingOccurrences( of: "{fileId}", - with: fileId - ) + with: fileId ) let params: [String: Any?] = [:] @@ -146,7 +210,13 @@ open class Storage: Service { "content-type": "application/json" ] - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) + client.call( + method: "DELETE", + path: path, + headers: headers, + params: params, + completion: completion + ) } /// @@ -160,19 +230,26 @@ open class Storage: Service { /// @throws Exception /// @return array /// - open func getFileDownload(_ fileId: String, completion: ((Result) -> Void)? = nil) { + open func getFileDownload( + fileId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/storage/files/{fileId}/download" path = path.replacingOccurrences( of: "{fileId}", - with: fileId - ) + with: fileId ) let params: [String: Any?] = [ "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -186,6 +263,7 @@ open class Storage: Service { /// @param String fileId /// @param Int width /// @param Int height + /// @param String gravity /// @param Int quality /// @param Int borderWidth /// @param String borderColor @@ -197,17 +275,31 @@ open class Storage: Service { /// @throws Exception /// @return array /// - open func getFilePreview(_ fileId: String, _ width: Int = 0, _ height: Int = 0, _ quality: Int = 100, _ borderWidth: Int = 0, _ borderColor: String = "", _ borderRadius: Int = 0, _ opacity: Double = 1.0, _ rotation: Int = 0, _ background: String = "", _ output: String = "", completion: ((Result) -> Void)? = nil) { + open func getFilePreview( + fileId: String, + width: Int? = nil, + height: Int? = nil, + gravity: String? = nil, + quality: Int? = nil, + borderWidth: Int? = nil, + borderColor: String? = nil, + borderRadius: Int? = nil, + opacity: Double? = nil, + rotation: Int? = nil, + background: String? = nil, + output: String? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/storage/files/{fileId}/preview" path = path.replacingOccurrences( of: "{fileId}", - with: fileId - ) + with: fileId ) let params: [String: Any?] = [ "width": width, "height": height, + "gravity": gravity, "quality": quality, "borderWidth": borderWidth, "borderColor": borderColor, @@ -219,7 +311,12 @@ open class Storage: Service { "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } /// @@ -233,19 +330,26 @@ open class Storage: Service { /// @throws Exception /// @return array /// - open func getFileView(_ fileId: String, completion: ((Result) -> Void)? = nil) { + open func getFileView( + fileId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/storage/files/{fileId}/view" path = path.replacingOccurrences( of: "{fileId}", - with: fileId - ) + with: fileId ) let params: [String: Any?] = [ "project": client.config["project"] ] - client.call(method: "GET", path: path, params: params, completion: completion) + client.call( + method: "GET", + path: path, + params: params, + completion: completion + ) } } diff --git a/Sources/Appwrite/Services/Teams.swift b/Sources/Appwrite/Services/Teams.swift index daa407b..5be4ef2 100644 --- a/Sources/Appwrite/Services/Teams.swift +++ b/Sources/Appwrite/Services/Teams.swift @@ -1,6 +1,7 @@ import AsyncHTTPClient import Foundation import NIO +import AppwriteModels open class Teams: Service { /// @@ -18,7 +19,13 @@ open class Teams: Service { /// @throws Exception /// @return array /// - open func list(_ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { + open func list( + search: String? = nil, + limit: Int? = nil, + offset: Int? = nil, + orderType: String? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/teams" let params: [String: Any?] = [ @@ -32,7 +39,18 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.TeamList = { dict in + return AppwriteModels.TeamList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -44,11 +62,15 @@ open class Teams: Service { /// project. /// /// @param String name - /// @param Array? roles + /// @param [Any] roles /// @throws Exception /// @return array /// - open func create(_ name: String, _ roles: Array? = nil, completion: ((Result) -> Void)? = nil) { + open func create( + name: String, + roles: [Any]? = nil, + completion: ((Result) -> Void)? = nil + ) { let path: String = "/teams" let params: [String: Any?] = [ @@ -60,7 +82,18 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Team = { dict in + return AppwriteModels.Team.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -73,13 +106,15 @@ open class Teams: Service { /// @throws Exception /// @return array /// - open func get(_ teamId: String, completion: ((Result) -> Void)? = nil) { + open func get( + teamId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) let params: [String: Any?] = [:] @@ -87,7 +122,18 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Team = { dict in + return AppwriteModels.Team.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -101,13 +147,16 @@ open class Teams: Service { /// @throws Exception /// @return array /// - open func update(_ teamId: String, _ name: String, completion: ((Result) -> Void)? = nil) { + open func update( + teamId: String, + name: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) let params: [String: Any?] = [ "name": name @@ -117,7 +166,18 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "PUT", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Team = { dict in + return AppwriteModels.Team.from(map: dict) + } + + client.call( + method: "PUT", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -130,13 +190,15 @@ open class Teams: Service { /// @throws Exception /// @return array /// - open func delete(_ teamId: String, completion: ((Result) -> Void)? = nil) { + open func delete( + teamId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) let params: [String: Any?] = [:] @@ -144,7 +206,13 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) + client.call( + method: "DELETE", + path: path, + headers: headers, + params: params, + completion: completion + ) } /// @@ -161,13 +229,19 @@ open class Teams: Service { /// @throws Exception /// @return array /// - open func getMemberships(_ teamId: String, _ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { + open func getMemberships( + teamId: String, + search: String? = nil, + limit: Int? = nil, + offset: Int? = nil, + orderType: String? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}/memberships" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) let params: [String: Any?] = [ "search": search, @@ -180,20 +254,34 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.MembershipList = { dict in + return AppwriteModels.MembershipList.from(map: dict) + } + + client.call( + method: "GET", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// /// Create Team Membership /// - /// Use this endpoint to invite a new member to join your team. An email with a - /// link to join the team will be sent to the new member email address if the - /// member doesn't exist in the project it will be created automatically. + /// Use this endpoint to invite a new member to join your team. If initiated + /// from Client SDK, an email with a link to join the team will be sent to the + /// new member's email address if the member doesn't exist in the project it + /// will be created automatically. If initiated from server side SDKs, new + /// member will automatically be added to the team. /// /// Use the 'URL' parameter to redirect the user from the invitation email back /// to your app. When the user is redirected, use the [Update Team Membership /// Status](/docs/client/teams#teamsUpdateMembershipStatus) endpoint to allow - /// the user to accept the invitation to the team. + /// the user to accept the invitation to the team. While calling from side + /// SDKs the redirect url can be empty string. /// /// Please note that in order to avoid a [Redirect /// Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) @@ -202,32 +290,49 @@ open class Teams: Service { /// /// @param String teamId /// @param String email - /// @param Array? roles + /// @param [Any] roles /// @param String url /// @param String name /// @throws Exception /// @return array /// - open func createMembership(_ teamId: String, _ email: String, _ roles: Array?, _ url: String, _ name: String = "", completion: ((Result) -> Void)? = nil) { + open func createMembership( + teamId: String, + email: String, + roles: [Any], + url: String, + name: String? = nil, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}/memberships" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) let params: [String: Any?] = [ "email": email, - "name": name, "roles": roles, - "url": url + "url": url, + "name": name ] let headers: [String: String] = [ "content-type": "application/json" ] - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Membership = { dict in + return AppwriteModels.Membership.from(map: dict) + } + + client.call( + method: "POST", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -235,22 +340,25 @@ open class Teams: Service { /// /// @param String teamId /// @param String membershipId - /// @param Array? roles + /// @param [Any] roles /// @throws Exception /// @return array /// - open func updateMembershipRoles(_ teamId: String, _ membershipId: String, _ roles: Array?, completion: ((Result) -> Void)? = nil) { + open func updateMembershipRoles( + teamId: String, + membershipId: String, + roles: [Any], + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}/memberships/{membershipId}" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) path = path.replacingOccurrences( of: "{membershipId}", - with: membershipId - ) + with: membershipId ) let params: [String: Any?] = [ "roles": roles @@ -260,7 +368,18 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Membership = { dict in + return AppwriteModels.Membership.from(map: dict) + } + + client.call( + method: "PATCH", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } /// @@ -275,18 +394,20 @@ open class Teams: Service { /// @throws Exception /// @return array /// - open func deleteMembership(_ teamId: String, _ membershipId: String, completion: ((Result) -> Void)? = nil) { + open func deleteMembership( + teamId: String, + membershipId: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}/memberships/{membershipId}" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) path = path.replacingOccurrences( of: "{membershipId}", - with: membershipId - ) + with: membershipId ) let params: [String: Any?] = [:] @@ -294,7 +415,13 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) + client.call( + method: "DELETE", + path: path, + headers: headers, + params: params, + completion: completion + ) } /// @@ -311,18 +438,22 @@ open class Teams: Service { /// @throws Exception /// @return array /// - open func updateMembershipStatus(_ teamId: String, _ membershipId: String, _ userId: String, _ secret: String, completion: ((Result) -> Void)? = nil) { + open func updateMembershipStatus( + teamId: String, + membershipId: String, + userId: String, + secret: String, + completion: ((Result) -> Void)? = nil + ) { var path: String = "/teams/{teamId}/memberships/{membershipId}/status" path = path.replacingOccurrences( of: "{teamId}", - with: teamId - ) + with: teamId ) path = path.replacingOccurrences( of: "{membershipId}", - with: membershipId - ) + with: membershipId ) let params: [String: Any?] = [ "userId": userId, @@ -333,7 +464,18 @@ open class Teams: Service { "content-type": "application/json" ] - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) + let convert: ([String: Any]) -> AppwriteModels.Membership = { dict in + return AppwriteModels.Membership.from(map: dict) + } + + client.call( + method: "PATCH", + path: path, + headers: headers, + params: params, + convert: convert, + completion: completion + ) } } diff --git a/Sources/Appwrite/Services/Users.swift b/Sources/Appwrite/Services/Users.swift deleted file mode 100644 index b2a9902..0000000 --- a/Sources/Appwrite/Services/Users.swift +++ /dev/null @@ -1,310 +0,0 @@ -import AsyncHTTPClient -import Foundation -import NIO - -open class Users: Service { - /// - /// List Users - /// - /// Get a list of all the project's users. You can use the query params to - /// filter your results. - /// - /// @param String search - /// @param Int limit - /// @param Int offset - /// @param String orderType - /// @throws Exception - /// @return array - /// - open func list(_ search: String = "", _ limit: Int = 25, _ offset: Int = 0, _ orderType: String = "ASC", completion: ((Result) -> Void)? = nil) { - let path: String = "/users" - - let params: [String: Any?] = [ - "search": search, - "limit": limit, - "offset": offset, - "orderType": orderType - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Create User - /// - /// Create a new user. - /// - /// @param String email - /// @param String password - /// @param String name - /// @throws Exception - /// @return array - /// - open func create(_ email: String, _ password: String, _ name: String = "", completion: ((Result) -> Void)? = nil) { - let path: String = "/users" - - let params: [String: Any?] = [ - "email": email, - "password": password, - "name": name - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "POST", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get User - /// - /// Get a user by its unique ID. - /// - /// @param String userId - /// @throws Exception - /// @return array - /// - open func get(_ userId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete User - /// - /// Delete a user by its unique ID. - /// - /// @param String userId - /// @throws Exception - /// @return array - /// - open func delete(_ userId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get User Logs - /// - /// Get a user activity logs list by its unique ID. - /// - /// @param String userId - /// @throws Exception - /// @return array - /// - open func getLogs(_ userId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}/logs" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get User Preferences - /// - /// Get the user preferences by its unique ID. - /// - /// @param String userId - /// @throws Exception - /// @return array - /// - open func getPrefs(_ userId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}/prefs" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update User Preferences - /// - /// Update the user preferences by its unique ID. You can pass only the - /// specific settings you wish to update. - /// - /// @param String userId - /// @param Any? prefs - /// @throws Exception - /// @return array - /// - open func updatePrefs(_ userId: String, _ prefs: Any?, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}/prefs" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [ - "prefs": prefs - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Get User Sessions - /// - /// Get the user sessions list by its unique ID. - /// - /// @param String userId - /// @throws Exception - /// @return array - /// - open func getSessions(_ userId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}/sessions" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "GET", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete User Sessions - /// - /// Delete all user's sessions by using the user's unique ID. - /// - /// @param String userId - /// @throws Exception - /// @return array - /// - open func deleteSessions(_ userId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}/sessions" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Delete User Session - /// - /// Delete a user sessions by its unique ID. - /// - /// @param String userId - /// @param String sessionId - /// @throws Exception - /// @return array - /// - open func deleteSession(_ userId: String, _ sessionId: String, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}/sessions/{sessionId}" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - path = path.replacingOccurrences( - of: "{sessionId}", - with: sessionId - ) - - let params: [String: Any?] = [:] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "DELETE", path: path, headers: headers, params: params, completion: completion) - } - - /// - /// Update User Status - /// - /// Update the user status by its unique ID. - /// - /// @param String userId - /// @param Int status - /// @throws Exception - /// @return array - /// - open func updateStatus(_ userId: String, _ status: Int, completion: ((Result) -> Void)? = nil) { - var path: String = "/users/{userId}/status" - - path = path.replacingOccurrences( - of: "{userId}", - with: userId - ) - - let params: [String: Any?] = [ - "status": status - ] - - let headers: [String: String] = [ - "content-type": "application/json" - ] - - client.call(method: "PATCH", path: path, headers: headers, params: params, completion: completion) - } - -} diff --git a/Sources/Appwrite/StreamingDelegate.swift b/Sources/Appwrite/StreamingDelegate.swift index 5b14e13..c80dc4e 100644 --- a/Sources/Appwrite/StreamingDelegate.swift +++ b/Sources/Appwrite/StreamingDelegate.swift @@ -11,7 +11,7 @@ class StreamingDelegate: HTTPClientResponseDelegate { case head(HTTPResponseHead) case body(HTTPResponseHead) case end - case error(Error) + case error(Swift.Error) } var state = State.idle @@ -117,7 +117,7 @@ class StreamingDelegate: HTTPClientResponseDelegate { } } - func didReceiveError(task: HTTPClient.Task, _ error: Error) { + func didReceiveError(task: HTTPClient.Task, _ error: Swift.Error) { state = .error(error) reportError?(AppwriteError(message: error.localizedDescription)) } diff --git a/Sources/Appwrite/WebSockets/HTTPHandler.swift b/Sources/Appwrite/WebSockets/HTTPHandler.swift new file mode 100644 index 0000000..75a7c15 --- /dev/null +++ b/Sources/Appwrite/WebSockets/HTTPHandler.swift @@ -0,0 +1,89 @@ +import NIO +import NIOHTTP1 +import Foundation + +/// Handles the HTTP pipeline for opening a WebSocket connection. +/// +/// Adds the required headers to the outbound upgrade connection request and handles success and failures responses. +class HTTPHandler { + + unowned let client: WebSocketClient + + let headers: HTTPHeaders + + init(client: WebSocketClient, headers: HTTPHeaders) { + self.client = client + self.headers = headers + } + + func upgradeFailure(status: HTTPResponseStatus) { + if let delegate = client.delegate { + switch status { + case .badRequest: + try! delegate.onError(error: WebSocketClientError.badRequest, status: status) + case .notFound: + try! delegate.onError(error: WebSocketClientError.notFound, status: status) + default: + break + } + } else { + switch status { + case .badRequest: + client.onError(WebSocketClientError.badRequest, status) + case .notFound: + client.onError(WebSocketClientError.notFound, status) + default: + break + } + } + } +} + +extension HTTPHandler : ChannelInboundHandler, RemovableChannelHandler { + + public typealias InboundIn = HTTPClientResponsePart + public typealias OutboundOut = HTTPClientRequestPart + + func channelActive(context: ChannelHandlerContext) { + var headers = HTTPHeaders() + + headers.add(name: "Host", value: "\(client.host):\(client.port)") + headers.add(name: "Content-Type", value: "text/plain") + headers.add(name: "Content-Length", value: "\(1)") + headers.add(contentsOf: self.headers) + let requestHead = HTTPRequestHead( + version: .http1_1, + method: .GET, + uri: "\(client.uri)?\(client.query)", + headers: headers + ) + + context.write(wrapOutboundOut(.head(requestHead)), promise: nil) + context.write(wrapOutboundOut(.body(.byteBuffer(ByteBuffer(string: "\r\n")))), promise: nil) + context.writeAndFlush(wrapOutboundOut(.end(nil)), promise: nil) + } + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let response = unwrapInboundIn(data) + + switch response { + case .head(let header): + print(String(describing: response)) + upgradeFailure(status: header.status) + break + case .body(var body): + print(body.readString(length: body.readableBytes)!) + break + case .end(_): + break + } + } + + func errorCaught(context: ChannelHandlerContext, error: Swift.Error) { + if client.delegate != nil { + try! client.delegate?.onError(error: error, status: nil) + } else { + client.onError(error, nil) + } + } +} diff --git a/Sources/Appwrite/WebSockets/MessageHandler.swift b/Sources/Appwrite/WebSockets/MessageHandler.swift new file mode 100644 index 0000000..330b526 --- /dev/null +++ b/Sources/Appwrite/WebSockets/MessageHandler.swift @@ -0,0 +1,137 @@ +import Foundation +import NIO +import NIOHTTP1 +import NIOWebSocket + +/// Handles the HTTP pipeline for opening a WebSocket connection. +/// +/// Adds the required headers to the outbound upgrade connection request and handles success and failures responses. +class MessageHandler { + + private let client: WebSocketClient + private var buffer: ByteBuffer + private var binaryBuffer: Data = Data() + private var isText: Bool = false + private var string: String = "" + + public init(client: WebSocketClient) { + self.client = client + self.buffer = ByteBufferAllocator().buffer(capacity: 0) + } + + private func unmaskedData(frame: WebSocketFrame) -> ByteBuffer { + var frameData = frame.data + if let maskingKey = frame.maskKey { + frameData.webSocketUnmask(maskingKey) + } + return frameData + } +} + +extension MessageHandler: ChannelInboundHandler, RemovableChannelHandler { + + typealias InboundIn = WebSocketFrame + + public func channelRead(context: ChannelHandlerContext, data: NIOAny) { + let frame = self.unwrapInboundIn(data) + switch frame.opcode { + case .text: + let data = unmaskedData(frame: frame) + if frame.fin { + guard let text = data.getString(at: 0, length: data.readableBytes) else { + return + } + if let delegate = client.delegate { + try! delegate.onMessage(text: text) + } else { + client.onTextMessage(text) + } + } else { + isText = true + guard let text = data.getString(at: 0, length: data.readableBytes) else { + return + } + string = text + } + case .binary: + let data = unmaskedData(frame: frame) + if frame.fin { + guard let binaryData = data.getData(at: 0, length: data.readableBytes) else { + return + } + if let delegate = client.delegate { + try! delegate.onMessage(data: binaryData) + } else { + client.onBinaryMessage(binaryData) + } + } else { + guard let binaryData = data.getData(at: 0, length: data.readableBytes) else { + return + } + binaryBuffer = binaryData + } + case .continuation: + let data = unmaskedData(frame: frame) + if isText { + if frame.fin { + guard let text = data.getString(at: 0, length: data.readableBytes) else { + return + } + string.append(text) + isText = false + if let delegate = client.delegate { + try! delegate.onMessage(text: string) + } else { + client.onTextMessage(string) + } + } else { + guard let text = data.getString(at: 0, length: data.readableBytes) else { + return + } + string.append(text) + } + } else { + if frame.fin { + guard let binaryData = data.getData(at: 0, length: data.readableBytes) else { + return + } + binaryBuffer.append(binaryData) + if let delegate = client.delegate { + try! delegate.onMessage(data: binaryBuffer) + } else { + client.onBinaryMessage(binaryBuffer) + } + } else { + guard let binaryData = data.getData(at: 0, length: data.readableBytes) else { + return + } + binaryBuffer.append(binaryData) + } + } + case .connectionClose: + guard frame.fin else { + return + } + let data = frame.data + if !client.closeSent { + client.close(data: frame.data.getData(at: 0, length: frame.data.readableBytes) ?? Data()) + } + if let delegate = client.delegate { + delegate.onClose(channel: context.channel, data: data.getData(at: 0, length: data.readableBytes)!) + } else { + client.onClose(context.channel, data.getData(at: 0, length: data.readableBytes)!) + } + default: + break + } + } + + public func errorCaught(context: ChannelHandlerContext, error: Swift.Error) { + if client.delegate != nil { + try! client.delegate?.onError(error: error, status: nil) + } else { + client.onError(error, nil) + } + client.close() + } +} diff --git a/Sources/Appwrite/WebSockets/WebSocketClient.swift b/Sources/Appwrite/WebSockets/WebSocketClient.swift new file mode 100644 index 0000000..67cc396 --- /dev/null +++ b/Sources/Appwrite/WebSockets/WebSocketClient.swift @@ -0,0 +1,405 @@ +import Foundation +import NIO +import NIOHTTP1 +import NIOWebSocket +import Dispatch +import NIOFoundationCompat +import NIOSSL + +public let WEBSOCKET_LOCKER_QUEUE = "SyncLocker" + +/// Creates and manages connections to a WebSocket server. +/// +/// Creates a connection to the remote host and allows setting callbacks for messages sent from the WebSocket server. +public class WebSocketClient { + + // MARK: - Properties + let host: String + let port: Int + let uri: String + let query: String + let headers: HTTPHeaders + let frameKey: String + + public private(set) var maxFrameSize: Int + + var channel: Channel? = nil + var tlsEnabled: Bool = false + var closeSent: Bool = false + + let upgradedSignalled = DispatchSemaphore(value: 0) + let locker = DispatchQueue(label: WEBSOCKET_LOCKER_QUEUE) + let threadGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) + + weak var delegate: WebSocketClientDelegate? = nil + + /// Is this client currently connected to a WebSocket + public var isConnected: Bool { + channel?.isActive ?? false + } + + // MARK: - Stored callbacks + + private var _openCallback: (Channel) -> Void = { _ in } + var onOpen: (Channel) -> Void { + get { + return locker.sync { + return _openCallback + } + } + set { + locker.sync { + _openCallback = newValue + } + } + } + + private var _closeCallback: (Channel, Data) -> Void = { _,_ in } + var onClose: (Channel, Data) -> Void { + get { + return locker.sync { + return _closeCallback + } + } + set { + locker.sync { + _closeCallback = newValue + } + } + } + + private var _textCallback: (String) -> Void = { _ in } + var onTextMessage: (String) -> Void { + get { + return locker.sync { + return _textCallback + } + } + set { + locker.sync { + _textCallback = newValue + } + } + } + + private var _binaryCallback: (Data) -> Void = { _ in } + var onBinaryMessage: (Data) -> Void { + get { + return locker.sync { + return _binaryCallback + } + } + set { + locker.sync { + _binaryCallback = newValue + } + } + } + + private var _errorCallBack: (Swift.Error?, HTTPResponseStatus?) -> Void = { _,_ in } + var onError: (Swift.Error?, HTTPResponseStatus?) -> Void { + get { + return locker.sync { + return _errorCallBack + } + } + set { + locker.sync { + _errorCallBack = newValue + } + } + } + + // MARK: - Callback setters + + /// Set a callback to be fired when a WebSocket connection is opened. + /// + /// - parameters: + /// - callback: Callback to fie when a WebSocket connection is opened + public func onOpen(_ callback: @escaping (Channel) -> Void) { + onOpen = callback + } + + /// Set a callback to be fired when a WebSocket text message is received. + /// + /// - parameters: + /// - callback: Callback to fie when a WebSocket text message is received + public func onMessage(_ callback: @escaping (String) -> Void) { + onTextMessage = callback + } + + /// Set a callback to be fired when a WebSocket binary message is received. + /// + /// - parameters: + /// - callback: Callback to fie when a WebSocket binary message is received + public func onMessage(_ callback: @escaping (Data) -> Void) { + onBinaryMessage = callback + } + + /// Set a callback to be fired when a WebSocket close message is received. + /// + /// - parameters: + /// - callback: Callback to fie when a WebSocket close message is received + public func onClose(_ callback: @escaping (Channel, Data) -> Void) { + onClose = callback + } + + /// Set a callback to be fired when a WebSocket error occurs. + /// + /// - parameters: + /// - callback: Callback to fie when a WebSocket error occurs + public func onError(_ callback: @escaping (Swift.Error?, HTTPResponseStatus?) -> Void) { + onError = callback + } + + // MARK: - Constructors + + /// Create a new `WebSocketClient`. + /// + /// - parameters: + /// - host: Host name of the remote server + /// - port: Port number on which the remote server is listening + /// - uri: The "Request-URI" of the GET method, it is used to identify the endpoint of the WebSocket connection + /// - frameKey: The key sent by client which server has to include while building it's response. + /// - maxFrameSize: Maximum allowable frame size of WebSocket client is configured using this parameter. + /// - tlsEnabled: Is TLS enabled for this client. + /// - delegate: Delegate to handle message and error callbacks + public init?( + host: String, + port: Int, + uri: String, + query: String, + frameKey: String, + headers: HTTPHeaders = HTTPHeaders(), + maxFrameSize: Int = 14, + tlsEnabled: Bool = false, + delegate: WebSocketClientDelegate? = nil + ) { + self.host = host + self.port = port + self.uri = uri + self.query = query + self.headers = headers + self.frameKey = frameKey + self.maxFrameSize = maxFrameSize + self.tlsEnabled = tlsEnabled + self.delegate = delegate + } + + /// Create a new `WebSocketClient`. + /// + /// - parameters: + /// - url: The absolute URL of the GET method used to identify the WebSocket endpoint + /// - delegate: Delegate to handle message and error callbacks. + public init?( + _ url: String, + headers: HTTPHeaders = HTTPHeaders(), + delegate: WebSocketClientDelegate? = nil + ) { + let rawUrl = URL(string: url) + let hasTLS = rawUrl?.scheme == "wss" || rawUrl?.scheme == "https" + self.frameKey = "tergregfgbsfdgfdsfgdbv==" + self.host = rawUrl?.host ?? "localhost" + self.port = rawUrl?.port ?? (hasTLS ? 443 : 80) + self.uri = rawUrl?.path ?? "/" + self.query = rawUrl?.query ?? "" + self.headers = headers + self.maxFrameSize = 24 + self.tlsEnabled = hasTLS + self.delegate = delegate + } + + deinit { + try! threadGroup.syncShutdownGracefully() + } + + // MARK: - Open connection + + /// Open a connection to the configured host and attempt to upgrade the connection to a WebSocket. If successful the `onOpen` callback will fire, otherwise a connection error will be thrown from here. + public func connect() throws { + let socketOptions = ChannelOptions.socket( + SocketOptionLevel(SOL_SOCKET), + SO_REUSEPORT + ) + + let bootstrap = ClientBootstrap(group: threadGroup) + .channelOption(socketOptions, value: 1) + .channelInitializer(self.openChannel) + + _ = try bootstrap + .connect(host: self.host, port: self.port) + .wait() + + self.upgradedSignalled.wait() + } + + private func openChannel(channel: Channel) -> EventLoopFuture { + let httpHandler = HTTPHandler(client: self, headers: headers) + + let basicUpgrader = NIOWebSocketClientUpgrader( + requestKey: self.frameKey, + upgradePipelineHandler: self.upgradePipelineHandler + ) + + let config: NIOHTTPClientUpgradeConfiguration = (upgraders: [basicUpgrader], completionHandler: { context in + context.channel.pipeline.removeHandler(httpHandler, promise: nil) + }) + + return channel.pipeline.addHTTPClientHandlers(withClientUpgrade: config).flatMap { _ in + return channel.pipeline.addHandler(httpHandler).flatMap { _ in + if self.tlsEnabled { + let tlsConfig = TLSConfiguration.makeClientConfiguration() + let sslContext = try! NIOSSLContext(configuration: tlsConfig) + let sslHandler = try! NIOSSLClientHandler(context: sslContext, serverHostname: self.host) + return channel.pipeline.addHandler(sslHandler, position: .first) + } else { + return channel.eventLoop.makeSucceededFuture(()) + } + } + } + } + + private func upgradePipelineHandler(channel: Channel, response: HTTPResponseHead) -> EventLoopFuture { + self.onOpen(channel) + + let handler = MessageHandler(client: self) + + if response.status == .switchingProtocols { + self.channel = channel + self.upgradedSignalled.signal() + } + + return channel.pipeline.addHandler(handler) + } + + // MARK: - Close connection + + /// Closes the connection + /// + /// - parameters: + /// - data: Close frame payload + public func close(data: Data = Data()) { + closeSent = true + + var buffer = ByteBufferAllocator() + .buffer(capacity: data.count) + + buffer.writeBytes(data) + + send( + data: buffer, + opcode: .connectionClose, + finalFrame: true + ) + } + + // MARK: - Send data + + /// Sends binary-formatted data to the connected server in multiple frames. + /// + /// - parameters: + /// - raw: Raw data to be sent in the frame + /// - opcode: Websocket opcode indicating type of the frame + /// - finalFrame: Whether the frame to be sent is the last one + public func send( + data: Data, + opcode: WebSocketOpcode, + finalFrame: Bool = true + ) { + var buffer = ByteBufferAllocator() + .buffer(capacity: data.count) + + buffer.writeBytes(data) + + if opcode == .connectionClose { + self.closeSent = true + } + + send( + data: buffer, + opcode: opcode, + finalFrame: finalFrame + ) + } + + /// Sends text-formatted data to the connected server in multiple frames. + /// + /// - parameters: + /// - raw: Raw text to be sent in the frame + /// - opcode: Websocket opcode indicating type of the frame + /// - finalFrame: Whether the frame to be sent is the last one + public func send( + text: String, + opcode: WebSocketOpcode = .text, + finalFrame: Bool = true + ) { + var buffer = ByteBufferAllocator() + .buffer(capacity: text.count) + + buffer.writeString(text) + + send( + data: buffer, + opcode: opcode, + finalFrame: finalFrame + ) + } + + + /// Sends the JSON representation of the given model to the connected server in multiple frames. + /// + /// - parameters: + /// - model: The model to encode and send + /// - opcode: Websocket opcode indicating type of the frame + /// - finalFrame: Whether the frame to be sent is the last one + public func send( + model: T, + opcode: WebSocketOpcode = .text, + finalFrame: Bool = true + ) { + let jsonEncoder = JSONEncoder() + do { + let jsonData = try jsonEncoder.encode(model) + let string = String(data: jsonData, encoding: .utf8)! + var buffer = ByteBufferAllocator() + .buffer(capacity: string.count) + + buffer.writeString(string) + + send( + data: buffer, + opcode: opcode, + finalFrame: finalFrame + ) + } catch let error { + print(error) + } + } + + /// Sends buffered bytes to the connected server in multiple frames. + /// + /// - parameters: + /// - model: The model to encode and send + /// - opcode: Websocket opcode indicating type of the frame + /// - finalFrame: Whether the frame to be sent is the last one + public func send( + data: ByteBuffer, + opcode: WebSocketOpcode, + finalFrame: Bool + ) { + let frame = WebSocketFrame( + fin: finalFrame, + opcode: opcode, + maskKey: nil, + data: data + ) + guard let channel = channel else { + return + } + if finalFrame { + channel.writeAndFlush(frame, promise: nil) + } else { + channel.write(frame, promise: nil) + } + } +} diff --git a/Sources/Appwrite/WebSockets/WebSocketClientDelegate.swift b/Sources/Appwrite/WebSockets/WebSocketClientDelegate.swift new file mode 100644 index 0000000..d1556ac --- /dev/null +++ b/Sources/Appwrite/WebSockets/WebSocketClientDelegate.swift @@ -0,0 +1,26 @@ +import Foundation +import NIO +import NIOHTTP1 + +/// Handles messages received by a connected WebSocket server. +public protocol WebSocketClientDelegate : AnyObject { + func onOpen(channel: Channel) + func onMessage(text: String) throws + func onMessage(data: Data) throws + func onClose(channel: Channel, data: Data) + func onError(error: Swift.Error?, status: HTTPResponseStatus?) throws +} + +// Add empty default implementations +extension WebSocketClientDelegate { + public func onOpen(channel: Channel) { + } + public func onMessage(text: String) { + } + public func onMessage(data: Data) { + } + public func onClose(channel: Channel, data: Data) { + } + public func onError(error: Swift.Error?, status: HTTPResponseStatus?) throws { + } +} diff --git a/Sources/Appwrite/WebSockets/WebSocketClientError.swift b/Sources/Appwrite/WebSockets/WebSocketClientError.swift new file mode 100644 index 0000000..d9445a9 --- /dev/null +++ b/Sources/Appwrite/WebSockets/WebSocketClientError.swift @@ -0,0 +1,14 @@ +/// Error mapped HTTP codes +enum WebSocketClientError: UInt, Swift.Error { + case notFound = 404 + case badRequest = 400 + + func code() -> UInt? { + switch self { + case .notFound: + return 404 + case .badRequest: + return 400 + } + } +} diff --git a/Sources/AppwriteModels/Continent.swift b/Sources/AppwriteModels/Continent.swift new file mode 100644 index 0000000..6535ffe --- /dev/null +++ b/Sources/AppwriteModels/Continent.swift @@ -0,0 +1,33 @@ + +/// Continent +public class Continent { + + /// Continent name. + public let name: String + + /// Continent two letter code. + public let code: String + + init( + name: String, + code: String + ) { + self.name = name + self.code = code + } + + public static func from(map: [String: Any]) -> Continent { + return Continent( + name: map["name"] as! String, + code: map["code"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "name": name as Any, + "code": code as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/ContinentList.swift b/Sources/AppwriteModels/ContinentList.swift new file mode 100644 index 0000000..2d2e488 --- /dev/null +++ b/Sources/AppwriteModels/ContinentList.swift @@ -0,0 +1,33 @@ + +/// Continents List +public class ContinentList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of continents. + public let continents: [Continent] + + init( + sum: Int, + continents: [Continent] + ) { + self.sum = sum + self.continents = continents + } + + public static func from(map: [String: Any]) -> ContinentList { + return ContinentList( + sum: map["sum"] as! Int, + continents: (map["continents"] as! [[String: Any]]).map { Continent.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "continents": continents.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Country.swift b/Sources/AppwriteModels/Country.swift new file mode 100644 index 0000000..20ba8ac --- /dev/null +++ b/Sources/AppwriteModels/Country.swift @@ -0,0 +1,33 @@ + +/// Country +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 + ) { + self.name = name + self.code = code + } + + public static func from(map: [String: Any]) -> Country { + return Country( + name: map["name"] as! String, + code: map["code"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "name": name as Any, + "code": code as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/CountryList.swift b/Sources/AppwriteModels/CountryList.swift new file mode 100644 index 0000000..15e1968 --- /dev/null +++ b/Sources/AppwriteModels/CountryList.swift @@ -0,0 +1,33 @@ + +/// Countries List +public class CountryList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of countries. + public let countries: [Country] + + init( + sum: Int, + countries: [Country] + ) { + self.sum = sum + self.countries = countries + } + + public static func from(map: [String: Any]) -> CountryList { + return CountryList( + sum: map["sum"] as! Int, + countries: (map["countries"] as! [[String: Any]]).map { Country.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "countries": countries.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Currency.swift b/Sources/AppwriteModels/Currency.swift new file mode 100644 index 0000000..ddd7569 --- /dev/null +++ b/Sources/AppwriteModels/Currency.swift @@ -0,0 +1,68 @@ + +/// Currency +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, + symbolNative: String, + decimalDigits: Int, + rounding: Double, + code: String, + namePlural: String + ) { + self.symbol = symbol + self.name = name + self.symbolNative = symbolNative + self.decimalDigits = decimalDigits + self.rounding = rounding + self.code = code + self.namePlural = namePlural + } + + public static func from(map: [String: Any]) -> Currency { + return Currency( + symbol: map["symbol"] as! String, + name: map["name"] as! String, + symbolNative: map["symbolNative"] as! String, + decimalDigits: map["decimalDigits"] as! Int, + rounding: map["rounding"] as! Double, + code: map["code"] as! String, + namePlural: map["namePlural"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "symbol": symbol as Any, + "name": name as Any, + "symbolNative": symbolNative as Any, + "decimalDigits": decimalDigits as Any, + "rounding": rounding as Any, + "code": code as Any, + "namePlural": namePlural as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/CurrencyList.swift b/Sources/AppwriteModels/CurrencyList.swift new file mode 100644 index 0000000..569925e --- /dev/null +++ b/Sources/AppwriteModels/CurrencyList.swift @@ -0,0 +1,33 @@ + +/// Currencies List +public class CurrencyList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of currencies. + public let currencies: [Currency] + + init( + sum: Int, + currencies: [Currency] + ) { + self.sum = sum + self.currencies = currencies + } + + public static func from(map: [String: Any]) -> CurrencyList { + return CurrencyList( + sum: map["sum"] as! Int, + currencies: (map["currencies"] as! [[String: Any]]).map { Currency.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "currencies": currencies.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Document.swift b/Sources/AppwriteModels/Document.swift new file mode 100644 index 0000000..81c45ab --- /dev/null +++ b/Sources/AppwriteModels/Document.swift @@ -0,0 +1,50 @@ + +/// Document +public class Document { + + /// Document ID. + public let id: String + + /// Collection ID. + public let collection: String + + /// Document permissions. + public let permissions: Permissions + + let data: [String: Any] + + init( + id: String, + collection: String, + permissions: Permissions, + data: [String: Any] + ) { + self.id = id + self.collection = collection + self.permissions = permissions + self.data = data + } + + public static func from(map: [String: Any]) -> Document { + return Document( + id: map["$id"] as! String, + collection: map["$collection"] as! String, + permissions: Permissions.from(map: map["$permissions"] as! [String: Any]), + data: map + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "$collection": collection as Any, + "$permissions": permissions.toMap() as Any, + "data": data + ] + } + + public func convertTo(fromJson: ([String: Any]) -> T) -> T { + return fromJson(data) + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/DocumentList.swift b/Sources/AppwriteModels/DocumentList.swift new file mode 100644 index 0000000..e3bde3c --- /dev/null +++ b/Sources/AppwriteModels/DocumentList.swift @@ -0,0 +1,37 @@ + +/// Documents List +public class DocumentList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of documents. + public let documents: [Document] + + init( + sum: Int, + documents: [Document] + ) { + self.sum = sum + self.documents = documents + } + + public static func from(map: [String: Any]) -> DocumentList { + return DocumentList( + sum: map["sum"] as! Int, + documents: (map["documents"] as! [[String: Any]]).map { Document.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "documents": documents.map { $0.toMap() } as Any + ] + } + + public func convertTo(fromJson: ([String: Any]) -> T) -> [T] { + documents.map { d in d.convertTo(fromJson: fromJson) } + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Execution.swift b/Sources/AppwriteModels/Execution.swift new file mode 100644 index 0000000..66b0615 --- /dev/null +++ b/Sources/AppwriteModels/Execution.swift @@ -0,0 +1,89 @@ + +/// Execution +public class Execution { + + /// Execution ID. + public let id: String + + /// Execution permissions. + public let permissions: Permissions + + /// Function ID. + public let functionId: String + + /// The execution creation date in Unix timestamp. + public let dateCreated: Int + + /// 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 + + /// The script exit code. + public let exitCode: Int + + /// The script stdout output string. Logs the last 4,000 characters of the execution stdout output. + public let stdout: String + + /// The script stderr output string. Logs the last 4,000 characters of the execution stderr output + public let stderr: String + + /// The script execution time in seconds. + public let time: Double + + init( + id: String, + permissions: Permissions, + functionId: String, + dateCreated: Int, + trigger: String, + status: String, + exitCode: Int, + stdout: String, + stderr: String, + time: Double + ) { + self.id = id + self.permissions = permissions + self.functionId = functionId + self.dateCreated = dateCreated + self.trigger = trigger + self.status = status + self.exitCode = exitCode + self.stdout = stdout + self.stderr = stderr + self.time = time + } + + public static func from(map: [String: Any]) -> Execution { + return Execution( + id: map["$id"] as! String, + permissions: Permissions.from(map: map["$permissions"] as! [String: Any]), + functionId: map["functionId"] as! String, + dateCreated: map["dateCreated"] as! Int, + trigger: map["trigger"] as! String, + status: map["status"] as! String, + exitCode: map["exitCode"] as! Int, + stdout: map["stdout"] as! String, + stderr: map["stderr"] as! String, + time: map["time"] as! Double + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "$permissions": permissions.toMap() as Any, + "functionId": functionId as Any, + "dateCreated": dateCreated as Any, + "trigger": trigger as Any, + "status": status as Any, + "exitCode": exitCode as Any, + "stdout": stdout as Any, + "stderr": stderr as Any, + "time": time as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/ExecutionList.swift b/Sources/AppwriteModels/ExecutionList.swift new file mode 100644 index 0000000..d937508 --- /dev/null +++ b/Sources/AppwriteModels/ExecutionList.swift @@ -0,0 +1,33 @@ + +/// Executions List +public class ExecutionList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of executions. + public let executions: [Execution] + + init( + sum: Int, + executions: [Execution] + ) { + self.sum = sum + self.executions = executions + } + + public static func from(map: [String: Any]) -> ExecutionList { + return ExecutionList( + sum: map["sum"] as! Int, + executions: (map["executions"] as! [[String: Any]]).map { Execution.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "executions": executions.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/File.swift b/Sources/AppwriteModels/File.swift new file mode 100644 index 0000000..d0e9abe --- /dev/null +++ b/Sources/AppwriteModels/File.swift @@ -0,0 +1,68 @@ + +/// File +public class File { + + /// File ID. + public let id: String + + /// File permissions. + public let permissions: Permissions + + /// File name. + public let name: String + + /// File creation date in Unix timestamp. + public let dateCreated: Int + + /// File MD5 signature. + public let signature: String + + /// File mime type. + public let mimeType: String + + /// File original size in bytes. + public let sizeOriginal: Int + + init( + id: String, + permissions: Permissions, + name: String, + dateCreated: Int, + signature: String, + mimeType: String, + sizeOriginal: Int + ) { + self.id = id + self.permissions = permissions + self.name = name + self.dateCreated = dateCreated + self.signature = signature + self.mimeType = mimeType + self.sizeOriginal = sizeOriginal + } + + public static func from(map: [String: Any]) -> File { + return File( + id: map["$id"] as! String, + permissions: Permissions.from(map: map["$permissions"] as! [String: Any]), + name: map["name"] as! String, + dateCreated: map["dateCreated"] as! Int, + signature: map["signature"] as! String, + mimeType: map["mimeType"] as! String, + sizeOriginal: map["sizeOriginal"] as! Int + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "$permissions": permissions.toMap() as Any, + "name": name as Any, + "dateCreated": dateCreated as Any, + "signature": signature as Any, + "mimeType": mimeType as Any, + "sizeOriginal": sizeOriginal as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/FileList.swift b/Sources/AppwriteModels/FileList.swift new file mode 100644 index 0000000..3498e90 --- /dev/null +++ b/Sources/AppwriteModels/FileList.swift @@ -0,0 +1,33 @@ + +/// Files List +public class FileList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of files. + public let files: [File] + + init( + sum: Int, + files: [File] + ) { + self.sum = sum + self.files = files + } + + public static func from(map: [String: Any]) -> FileList { + return FileList( + sum: map["sum"] as! Int, + files: (map["files"] as! [[String: Any]]).map { File.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "files": files.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Jwt.swift b/Sources/AppwriteModels/Jwt.swift new file mode 100644 index 0000000..39c6892 --- /dev/null +++ b/Sources/AppwriteModels/Jwt.swift @@ -0,0 +1,26 @@ + +/// JWT +public class Jwt { + + /// JWT encoded string. + public let jwt: String + + init( + jwt: String + ) { + self.jwt = jwt + } + + public static func from(map: [String: Any]) -> Jwt { + return Jwt( + jwt: map["jwt"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "jwt": jwt as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Language.swift b/Sources/AppwriteModels/Language.swift new file mode 100644 index 0000000..5151938 --- /dev/null +++ b/Sources/AppwriteModels/Language.swift @@ -0,0 +1,40 @@ + +/// Language +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, + nativeName: String + ) { + self.name = name + self.code = code + self.nativeName = nativeName + } + + public static func from(map: [String: Any]) -> Language { + return Language( + name: map["name"] as! String, + code: map["code"] as! String, + nativeName: map["nativeName"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "name": name as Any, + "code": code as Any, + "nativeName": nativeName as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/LanguageList.swift b/Sources/AppwriteModels/LanguageList.swift new file mode 100644 index 0000000..cd50c66 --- /dev/null +++ b/Sources/AppwriteModels/LanguageList.swift @@ -0,0 +1,33 @@ + +/// Languages List +public class LanguageList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of languages. + public let languages: [Language] + + init( + sum: Int, + languages: [Language] + ) { + self.sum = sum + self.languages = languages + } + + public static func from(map: [String: Any]) -> LanguageList { + return LanguageList( + sum: map["sum"] as! Int, + languages: (map["languages"] as! [[String: Any]]).map { Language.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "languages": languages.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Locale.swift b/Sources/AppwriteModels/Locale.swift new file mode 100644 index 0000000..386e2a9 --- /dev/null +++ b/Sources/AppwriteModels/Locale.swift @@ -0,0 +1,68 @@ + +/// Locale +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 "AF" for Africa, "AN" for Antarctica, "AS" for Asia, "EU" for Europe, "NA" for North America, "OC" for Oceania, and "SA" for South America. + public let continentCode: String + + /// Continent name. This field support localization. + public let continent: String + + /// True if country is part of the Europian 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, + country: String, + continentCode: String, + continent: String, + eu: Bool, + currency: String + ) { + self.ip = ip + self.countryCode = countryCode + self.country = country + self.continentCode = continentCode + self.continent = continent + self.eu = eu + self.currency = currency + } + + public static func from(map: [String: Any]) -> Locale { + return Locale( + ip: map["ip"] as! String, + countryCode: map["countryCode"] as! String, + country: map["country"] as! String, + continentCode: map["continentCode"] as! String, + continent: map["continent"] as! String, + eu: map["eu"] as! Bool, + currency: map["currency"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "ip": ip as Any, + "countryCode": countryCode as Any, + "country": country as Any, + "continentCode": continentCode as Any, + "continent": continent as Any, + "eu": eu as Any, + "currency": currency as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Log.swift b/Sources/AppwriteModels/Log.swift new file mode 100644 index 0000000..fe4b2d5 --- /dev/null +++ b/Sources/AppwriteModels/Log.swift @@ -0,0 +1,138 @@ + +/// Log +public class Log { + + /// Event name. + public let event: String + + /// IP session in use when the session was created. + public let ip: String + + /// Log creation time in Unix timestamp. + public let time: Int + + /// 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, + ip: String, + time: Int, + osCode: String, + osName: String, + osVersion: String, + clientType: String, + clientCode: String, + clientName: String, + clientVersion: String, + clientEngine: String, + clientEngineVersion: String, + deviceName: String, + deviceBrand: String, + deviceModel: String, + countryCode: String, + countryName: String + ) { + self.event = event + self.ip = ip + self.time = time + self.osCode = osCode + self.osName = osName + self.osVersion = osVersion + self.clientType = clientType + self.clientCode = clientCode + self.clientName = clientName + self.clientVersion = clientVersion + self.clientEngine = clientEngine + self.clientEngineVersion = clientEngineVersion + self.deviceName = deviceName + self.deviceBrand = deviceBrand + self.deviceModel = deviceModel + self.countryCode = countryCode + self.countryName = countryName + } + + public static func from(map: [String: Any]) -> Log { + return Log( + event: map["event"] as! String, + ip: map["ip"] as! String, + time: map["time"] as! Int, + osCode: map["osCode"] as! String, + osName: map["osName"] as! String, + osVersion: map["osVersion"] as! String, + clientType: map["clientType"] as! String, + clientCode: map["clientCode"] as! String, + clientName: map["clientName"] as! String, + clientVersion: map["clientVersion"] as! String, + clientEngine: map["clientEngine"] as! String, + clientEngineVersion: map["clientEngineVersion"] as! String, + deviceName: map["deviceName"] as! String, + deviceBrand: map["deviceBrand"] as! String, + deviceModel: map["deviceModel"] as! String, + countryCode: map["countryCode"] as! String, + countryName: map["countryName"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "event": event as Any, + "ip": ip as Any, + "time": time as Any, + "osCode": osCode as Any, + "osName": osName as Any, + "osVersion": osVersion as Any, + "clientType": clientType as Any, + "clientCode": clientCode as Any, + "clientName": clientName as Any, + "clientVersion": clientVersion as Any, + "clientEngine": clientEngine as Any, + "clientEngineVersion": clientEngineVersion as Any, + "deviceName": deviceName as Any, + "deviceBrand": deviceBrand as Any, + "deviceModel": deviceModel as Any, + "countryCode": countryCode as Any, + "countryName": countryName as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/LogList.swift b/Sources/AppwriteModels/LogList.swift new file mode 100644 index 0000000..f86edb6 --- /dev/null +++ b/Sources/AppwriteModels/LogList.swift @@ -0,0 +1,26 @@ + +/// Logs List +public class LogList { + + /// List of logs. + public let logs: [Log] + + init( + logs: [Log] + ) { + self.logs = logs + } + + public static func from(map: [String: Any]) -> LogList { + return LogList( + logs: (map["logs"] as! [[String: Any]]).map { Log.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "logs": logs.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Membership.swift b/Sources/AppwriteModels/Membership.swift new file mode 100644 index 0000000..cf648f5 --- /dev/null +++ b/Sources/AppwriteModels/Membership.swift @@ -0,0 +1,82 @@ + +/// Membership +public class Membership { + + /// Membership ID. + public let id: String + + /// User ID. + public let userId: String + + /// Team ID. + public let teamId: String + + /// User name. + public let name: String + + /// User email address. + public let email: String + + /// Date, the user has been invited to join the team in Unix timestamp. + public let invited: Int + + /// Date, the user has accepted the invitation to join the team in Unix timestamp. + public let joined: Int + + /// User confirmation status, true if the user has joined the team or false otherwise. + public let confirm: Bool + + /// User list of roles + public let roles: [Any] + + init( + id: String, + userId: String, + teamId: String, + name: String, + email: String, + invited: Int, + joined: Int, + confirm: Bool, + roles: [Any] + ) { + self.id = id + self.userId = userId + self.teamId = teamId + self.name = name + self.email = email + self.invited = invited + self.joined = joined + self.confirm = confirm + self.roles = roles + } + + public static func from(map: [String: Any]) -> Membership { + return Membership( + id: map["$id"] as! String, + userId: map["userId"] as! String, + teamId: map["teamId"] as! String, + name: map["name"] as! String, + email: map["email"] as! String, + invited: map["invited"] as! Int, + joined: map["joined"] as! Int, + confirm: map["confirm"] as! Bool, + roles: map["roles"] as! [Any] + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "userId": userId as Any, + "teamId": teamId as Any, + "name": name as Any, + "email": email as Any, + "invited": invited as Any, + "joined": joined as Any, + "confirm": confirm as Any, + "roles": roles as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/MembershipList.swift b/Sources/AppwriteModels/MembershipList.swift new file mode 100644 index 0000000..49f2ecf --- /dev/null +++ b/Sources/AppwriteModels/MembershipList.swift @@ -0,0 +1,33 @@ + +/// Memberships List +public class MembershipList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of memberships. + public let memberships: [Membership] + + init( + sum: Int, + memberships: [Membership] + ) { + self.sum = sum + self.memberships = memberships + } + + public static func from(map: [String: Any]) -> MembershipList { + return MembershipList( + sum: map["sum"] as! Int, + memberships: (map["memberships"] as! [[String: Any]]).map { Membership.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "memberships": memberships.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Permissions.swift b/Sources/AppwriteModels/Permissions.swift new file mode 100644 index 0000000..6b3d411 --- /dev/null +++ b/Sources/AppwriteModels/Permissions.swift @@ -0,0 +1,33 @@ + +/// Permissions +public class Permissions { + + /// Read permissions. + public let read: [Any] + + /// Write permissions. + public let write: [Any] + + init( + read: [Any], + write: [Any] + ) { + self.read = read + self.write = write + } + + public static func from(map: [String: Any]) -> Permissions { + return Permissions( + read: map["read"] as! [Any], + write: map["write"] as! [Any] + ) + } + + public func toMap() -> [String: Any] { + return [ + "read": read as Any, + "write": write as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Phone.swift b/Sources/AppwriteModels/Phone.swift new file mode 100644 index 0000000..c8f02ac --- /dev/null +++ b/Sources/AppwriteModels/Phone.swift @@ -0,0 +1,40 @@ + +/// Phone +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, + countryName: String + ) { + self.code = code + self.countryCode = countryCode + self.countryName = countryName + } + + public static func from(map: [String: Any]) -> Phone { + return Phone( + code: map["code"] as! String, + countryCode: map["countryCode"] as! String, + countryName: map["countryName"] as! String + ) + } + + public func toMap() -> [String: Any] { + return [ + "code": code as Any, + "countryCode": countryCode as Any, + "countryName": countryName as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/PhoneList.swift b/Sources/AppwriteModels/PhoneList.swift new file mode 100644 index 0000000..85e162a --- /dev/null +++ b/Sources/AppwriteModels/PhoneList.swift @@ -0,0 +1,33 @@ + +/// Phones List +public class PhoneList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of phones. + public let phones: [Phone] + + init( + sum: Int, + phones: [Phone] + ) { + self.sum = sum + self.phones = phones + } + + public static func from(map: [String: Any]) -> PhoneList { + return PhoneList( + sum: map["sum"] as! Int, + phones: (map["phones"] as! [[String: Any]]).map { Phone.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "phones": phones.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Preferences.swift b/Sources/AppwriteModels/Preferences.swift new file mode 100644 index 0000000..9a3616b --- /dev/null +++ b/Sources/AppwriteModels/Preferences.swift @@ -0,0 +1,29 @@ + +/// Preferences +public class Preferences { + + let data: [String: Any] + + init( + data: [String: Any] + ) { + self.data = data + } + + public static func from(map: [String: Any]) -> Preferences { + return Preferences( + data: map + ) + } + + public func toMap() -> [String: Any] { + return [ + "data": data + ] + } + + public func convertTo(fromJson: ([String: Any]) -> T) -> T { + return fromJson(data) + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Session.swift b/Sources/AppwriteModels/Session.swift new file mode 100644 index 0000000..3a2a8d6 --- /dev/null +++ b/Sources/AppwriteModels/Session.swift @@ -0,0 +1,173 @@ + +/// Session +public class Session { + + /// Session ID. + public let id: String + + /// User ID. + public let userId: String + + /// Session expiration date in Unix timestamp. + public let expire: Int + + /// Session Provider. + public let provider: String + + /// Session Provider User ID. + public let providerUid: String + + /// Session Provider Token. + public let providerToken: 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 + + init( + id: String, + userId: String, + expire: Int, + provider: String, + providerUid: String, + providerToken: String, + ip: String, + osCode: String, + osName: String, + osVersion: String, + clientType: String, + clientCode: String, + clientName: String, + clientVersion: String, + clientEngine: String, + clientEngineVersion: String, + deviceName: String, + deviceBrand: String, + deviceModel: String, + countryCode: String, + countryName: String, + current: Bool + ) { + self.id = id + self.userId = userId + self.expire = expire + self.provider = provider + self.providerUid = providerUid + self.providerToken = providerToken + self.ip = ip + self.osCode = osCode + self.osName = osName + self.osVersion = osVersion + self.clientType = clientType + self.clientCode = clientCode + self.clientName = clientName + self.clientVersion = clientVersion + self.clientEngine = clientEngine + self.clientEngineVersion = clientEngineVersion + self.deviceName = deviceName + self.deviceBrand = deviceBrand + self.deviceModel = deviceModel + self.countryCode = countryCode + self.countryName = countryName + self.current = current + } + + public static func from(map: [String: Any]) -> Session { + return Session( + id: map["$id"] as! String, + userId: map["userId"] as! String, + expire: map["expire"] as! Int, + provider: map["provider"] as! String, + providerUid: map["providerUid"] as! String, + providerToken: map["providerToken"] as! String, + ip: map["ip"] as! String, + osCode: map["osCode"] as! String, + osName: map["osName"] as! String, + osVersion: map["osVersion"] as! String, + clientType: map["clientType"] as! String, + clientCode: map["clientCode"] as! String, + clientName: map["clientName"] as! String, + clientVersion: map["clientVersion"] as! String, + clientEngine: map["clientEngine"] as! String, + clientEngineVersion: map["clientEngineVersion"] as! String, + deviceName: map["deviceName"] as! String, + deviceBrand: map["deviceBrand"] as! String, + deviceModel: map["deviceModel"] as! String, + countryCode: map["countryCode"] as! String, + countryName: map["countryName"] as! String, + current: map["current"] as! Bool + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "userId": userId as Any, + "expire": expire as Any, + "provider": provider as Any, + "providerUid": providerUid as Any, + "providerToken": providerToken as Any, + "ip": ip as Any, + "osCode": osCode as Any, + "osName": osName as Any, + "osVersion": osVersion as Any, + "clientType": clientType as Any, + "clientCode": clientCode as Any, + "clientName": clientName as Any, + "clientVersion": clientVersion as Any, + "clientEngine": clientEngine as Any, + "clientEngineVersion": clientEngineVersion as Any, + "deviceName": deviceName as Any, + "deviceBrand": deviceBrand as Any, + "deviceModel": deviceModel as Any, + "countryCode": countryCode as Any, + "countryName": countryName as Any, + "current": current as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/SessionList.swift b/Sources/AppwriteModels/SessionList.swift new file mode 100644 index 0000000..a80ce7b --- /dev/null +++ b/Sources/AppwriteModels/SessionList.swift @@ -0,0 +1,33 @@ + +/// Sessions List +public class SessionList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of sessions. + public let sessions: [Session] + + init( + sum: Int, + sessions: [Session] + ) { + self.sum = sum + self.sessions = sessions + } + + public static func from(map: [String: Any]) -> SessionList { + return SessionList( + sum: map["sum"] as! Int, + sessions: (map["sessions"] as! [[String: Any]]).map { Session.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "sessions": sessions.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Team.swift b/Sources/AppwriteModels/Team.swift new file mode 100644 index 0000000..bfeec49 --- /dev/null +++ b/Sources/AppwriteModels/Team.swift @@ -0,0 +1,47 @@ + +/// Team +public class Team { + + /// Team ID. + public let id: String + + /// Team name. + public let name: String + + /// Team creation date in Unix timestamp. + public let dateCreated: Int + + /// Total sum of team members. + public let sum: Int + + init( + id: String, + name: String, + dateCreated: Int, + sum: Int + ) { + self.id = id + self.name = name + self.dateCreated = dateCreated + self.sum = sum + } + + public static func from(map: [String: Any]) -> Team { + return Team( + id: map["$id"] as! String, + name: map["name"] as! String, + dateCreated: map["dateCreated"] as! Int, + sum: map["sum"] as! Int + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "name": name as Any, + "dateCreated": dateCreated as Any, + "sum": sum as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/TeamList.swift b/Sources/AppwriteModels/TeamList.swift new file mode 100644 index 0000000..5e6f893 --- /dev/null +++ b/Sources/AppwriteModels/TeamList.swift @@ -0,0 +1,33 @@ + +/// Teams List +public class TeamList { + + /// Total number of items available on the server. + public let sum: Int + + /// List of teams. + public let teams: [Team] + + init( + sum: Int, + teams: [Team] + ) { + self.sum = sum + self.teams = teams + } + + public static func from(map: [String: Any]) -> TeamList { + return TeamList( + sum: map["sum"] as! Int, + teams: (map["teams"] as! [[String: Any]]).map { Team.from(map: $0) } + ) + } + + public func toMap() -> [String: Any] { + return [ + "sum": sum as Any, + "teams": teams.map { $0.toMap() } as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/Token.swift b/Sources/AppwriteModels/Token.swift new file mode 100644 index 0000000..3238c90 --- /dev/null +++ b/Sources/AppwriteModels/Token.swift @@ -0,0 +1,47 @@ + +/// Token +public class Token { + + /// Token ID. + public let id: 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 Unix timestamp. + public let expire: Int + + init( + id: String, + userId: String, + secret: String, + expire: Int + ) { + self.id = id + self.userId = userId + self.secret = secret + self.expire = expire + } + + public static func from(map: [String: Any]) -> Token { + return Token( + id: map["$id"] as! String, + userId: map["userId"] as! String, + secret: map["secret"] as! String, + expire: map["expire"] as! Int + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "userId": userId as Any, + "secret": secret as Any, + "expire": expire as Any + ] + } + +} \ No newline at end of file diff --git a/Sources/AppwriteModels/User.swift b/Sources/AppwriteModels/User.swift new file mode 100644 index 0000000..ff200e8 --- /dev/null +++ b/Sources/AppwriteModels/User.swift @@ -0,0 +1,75 @@ + +/// User +public class User { + + /// User ID. + public let id: String + + /// User name. + public let name: String + + /// User registration date in Unix timestamp. + public let registration: Int + + /// User status. 0 for Unactivated, 1 for active and 2 is blocked. + public let status: Int + + /// Unix timestamp of the most recent password update + public let passwordUpdate: Int + + /// User email address. + public let email: String + + /// Email verification status. + public let emailVerification: Bool + + /// User preferences as a key-value object + public let prefs: Preferences + + init( + id: String, + name: String, + registration: Int, + status: Int, + passwordUpdate: Int, + email: String, + emailVerification: Bool, + prefs: Preferences + ) { + self.id = id + self.name = name + self.registration = registration + self.status = status + self.passwordUpdate = passwordUpdate + self.email = email + self.emailVerification = emailVerification + self.prefs = prefs + } + + public static func from(map: [String: Any]) -> User { + return User( + id: map["$id"] as! String, + name: map["name"] as! String, + registration: map["registration"] as! Int, + status: map["status"] as! Int, + passwordUpdate: map["passwordUpdate"] as! Int, + email: map["email"] as! String, + emailVerification: map["emailVerification"] as! Bool, + prefs: Preferences.from(map: map["prefs"] as! [String: Any]) + ) + } + + public func toMap() -> [String: Any] { + return [ + "$id": id as Any, + "name": name as Any, + "registration": registration as Any, + "status": status as Any, + "passwordUpdate": passwordUpdate as Any, + "email": email as Any, + "emailVerification": emailVerification as Any, + "prefs": prefs.toMap() as Any + ] + } + +} \ No newline at end of file diff --git a/Tests/AppwriteTests/Tests.swift b/Tests/AppwriteTests/Tests.swift new file mode 100644 index 0000000..a93a0ad --- /dev/null +++ b/Tests/AppwriteTests/Tests.swift @@ -0,0 +1,222 @@ +import XCTest +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif +import Appwrite +import AsyncHTTPClient +import NIO + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + self.writeToFile(string: "Test Started") + } + + override func tearDown() { + super.tearDown() + } + + func test() throws { + let group = DispatchGroup() + + let client = Client() + .setEndpointRealtime("wss://demo.appwrite.io/v1") + .setProject("console") + .addHeader(key: "Origin", value: "http://localhost") + .setSelfSigned() + + let foo = Foo(client) + let bar = Bar(client) + let general = General(client) + let realtime = Realtime(client) + var realtimeResponse = "Realtime failed!" + + realtime.subscribe(channels: ["tests"]) { message in + realtimeResponse = message.payload!["response"] as! String + } + + // Foo Tests + group.enter() + foo.get(x: "string", y: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + foo.post(x: "string", y: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + foo.put(x: "string", y: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + foo.patch(x: "string", y: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + foo.delete(x: "string", y: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + + // Bar Tests + group.enter() + bar.get(xrequired: "string", xdefault: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + bar.post(xrequired: "string", xdefault: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + bar.put(xrequired: "string", xdefault: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + bar.patch(xrequired: "string", xdefault: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + group.enter() + bar.delete(xrequired: "string", xdefault: 123, z: ["string in array"]) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + + // General Tests + group.enter() + general.redirect() { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: (mock as! [String: Any])["result"] as! String) + } + group.leave() + } + group.wait() + group.enter() + + let url = URL(fileURLWithPath: "\(FileManager.default.currentDirectoryPath)/../../resources/file.png") + let buffer = ByteBuffer(data: try! Data(contentsOf: url)) + let file = File(name: "file.png", buffer: buffer) + general.upload(x: "string", y: 123, z: ["string in array"], file: file) { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let mock): self.writeToFile(string: mock.result) + } + group.leave() + } + group.wait() + + group.enter() + general.error400() { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let error): self.writeToFile(string: error.message) + } + group.leave() + } + group.wait() + group.enter() + general.error500() { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let error): self.writeToFile(string: error.message) + } + group.leave() + } + group.wait() + group.enter() + general.error502() { result in + switch result { + case .failure(let error): self.writeToFile(string: error.message) + case .success(let error): self.writeToFile(string: (error as! Error).message) + } + group.leave() + } + group.wait() + + self.writeToFile(string: realtimeResponse) + } + + private func writeToFile(string: String) { + let url = URL(fileURLWithPath: "\(FileManager.default.currentDirectoryPath)/../../../result.txt") + try! string.appendLine(to: url) + } +} + +struct Response: Decodable { + let result: String? + let message: String? +} + +extension String { + func appendLine(to url: URL) throws { + try self.appending("\n").append(to: url) + } + + func append(to url: URL) throws { + let data = self.data(using: .utf8) + try data?.append(to: url) + } +} + +extension Data { + func append(to url: URL) throws { + if let fileHandle = try? FileHandle(forWritingTo: url) { + defer { + fileHandle.closeFile() + } + fileHandle.seekToEndOfFile() + fileHandle.write(self) + } else { + try write(to: url) + } + } +} \ No newline at end of file diff --git a/docs/examples/account/create-anonymous-session.md b/docs/examples/account/create-anonymous-session.md index 154e6bc..d6bb191 100644 --- a/docs/examples/account/create-anonymous-session.md +++ b/docs/examples/account/create-anonymous-session.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.createAnonymousSession() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let session): + print(String(describing: session) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/create-j-w-t.md b/docs/examples/account/create-j-w-t.md index b7898ee..b2797e7 100644 --- a/docs/examples/account/create-j-w-t.md +++ b/docs/examples/account/create-j-w-t.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.createJWT() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let jwt): + print(String(describing: jwt) } } } -``` \ No newline at end of file diff --git a/docs/examples/users/get.md b/docs/examples/account/create-magic-u-r-l-session.md similarity index 53% rename from docs/examples/users/get.md rename to docs/examples/account/create-magic-u-r-l-session.md index 47d3497..8ca61dd 100644 --- a/docs/examples/users/get.md +++ b/docs/examples/account/create-magic-u-r-l-session.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let users = Users(client: client) - users.get( - userId: "[USER_ID]" + let account = Account(client) + account.createMagicURLSession( + email: "email@example.com" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let token): + print(String(describing: token) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/create-o-auth2session.md b/docs/examples/account/create-o-auth2session.md index 928ca2e..cb1e4e3 100644 --- a/docs/examples/account/create-o-auth2session.md +++ b/docs/examples/account/create-o-auth2session.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,15 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.createOAuth2Session( provider: "amazon" - ) { + ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): + print(error.message) + case .success(let success): + print(String(describing: success) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/create-recovery.md b/docs/examples/account/create-recovery.md index 897f049..dcdfa51 100644 --- a/docs/examples/account/create-recovery.md +++ b/docs/examples/account/create-recovery.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.createRecovery( email: "email@example.com", url: "https://example.com" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let token): + print(String(describing: token) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/create-session.md b/docs/examples/account/create-session.md index 6b4a61d..a0d6d11 100644 --- a/docs/examples/account/create-session.md +++ b/docs/examples/account/create-session.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.createSession( email: "email@example.com", password: "password" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let session): + print(String(describing: session) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/create-verification.md b/docs/examples/account/create-verification.md index d402ccd..b144e94 100644 --- a/docs/examples/account/create-verification.md +++ b/docs/examples/account/create-verification.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.createVerification( url: "https://example.com" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let token): + print(String(describing: token) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/create.md b/docs/examples/account/create.md index e2d49e7..360d59c 100644 --- a/docs/examples/account/create.md +++ b/docs/examples/account/create.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.create( email: "email@example.com", password: "password" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let user): + print(String(describing: user) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/delete-session.md b/docs/examples/account/delete-session.md index 7f2929e..3d3da9f 100644 --- a/docs/examples/account/delete-session.md +++ b/docs/examples/account/delete-session.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.deleteSession( sessionId: "[SESSION_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let ): + print(String(describing: ) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/delete-sessions.md b/docs/examples/account/delete-sessions.md index 2c1737b..937e270 100644 --- a/docs/examples/account/delete-sessions.md +++ b/docs/examples/account/delete-sessions.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.deleteSessions() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let ): + print(String(describing: ) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/delete.md b/docs/examples/account/delete.md index 0ba38e7..e43e10c 100644 --- a/docs/examples/account/delete.md +++ b/docs/examples/account/delete.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.delete() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let ): + print(String(describing: ) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/get-logs.md b/docs/examples/account/get-logs.md index cc6e752..531b30a 100644 --- a/docs/examples/account/get-logs.md +++ b/docs/examples/account/get-logs.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.getLogs() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let logList): + print(String(describing: logList) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/get-prefs.md b/docs/examples/account/get-prefs.md index 1de3cee..d39f79d 100644 --- a/docs/examples/account/get-prefs.md +++ b/docs/examples/account/get-prefs.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.getPrefs() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let preferences): + print(String(describing: preferences) } } } -``` \ No newline at end of file diff --git a/docs/examples/users/delete-session.md b/docs/examples/account/get-session.md similarity index 55% rename from docs/examples/users/delete-session.md rename to docs/examples/account/get-session.md index 562377b..57244db 100644 --- a/docs/examples/users/delete-session.md +++ b/docs/examples/account/get-session.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let users = Users(client: client) - users.deleteSession( - userId: "[USER_ID]", + let account = Account(client) + account.getSession( sessionId: "[SESSION_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let session): + print(String(describing: session) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/get-sessions.md b/docs/examples/account/get-sessions.md index aed38ac..af03882 100644 --- a/docs/examples/account/get-sessions.md +++ b/docs/examples/account/get-sessions.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.getSessions() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let sessionList): + print(String(describing: sessionList) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/get.md b/docs/examples/account/get.md index 22b7a3a..21bd299 100644 --- a/docs/examples/account/get.md +++ b/docs/examples/account/get.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.get() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let user): + print(String(describing: user) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/update-email.md b/docs/examples/account/update-email.md index 6baea02..7e338be 100644 --- a/docs/examples/account/update-email.md +++ b/docs/examples/account/update-email.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.updateEmail( email: "email@example.com", password: "password" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let user): + print(String(describing: user) } } } -``` \ No newline at end of file diff --git a/docs/examples/users/update-prefs.md b/docs/examples/account/update-magic-u-r-l-session.md similarity index 56% rename from docs/examples/users/update-prefs.md rename to docs/examples/account/update-magic-u-r-l-session.md index bcf1151..1ea5db9 100644 --- a/docs/examples/users/update-prefs.md +++ b/docs/examples/account/update-magic-u-r-l-session.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let users = Users(client: client) - users.updatePrefs( + let account = Account(client) + account.updateMagicURLSession( userId: "[USER_ID]", - prefs: + secret: "[SECRET]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let session): + print(String(describing: session) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/update-name.md b/docs/examples/account/update-name.md index e46c077..6eb8e38 100644 --- a/docs/examples/account/update-name.md +++ b/docs/examples/account/update-name.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.updateName( name: "[NAME]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let user): + print(String(describing: user) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/update-password.md b/docs/examples/account/update-password.md index 488222d..bc5046e 100644 --- a/docs/examples/account/update-password.md +++ b/docs/examples/account/update-password.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.updatePassword( password: "password" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let user): + print(String(describing: user) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/update-prefs.md b/docs/examples/account/update-prefs.md index c72515f..0b82ed6 100644 --- a/docs/examples/account/update-prefs.md +++ b/docs/examples/account/update-prefs.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.updatePrefs( prefs: ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let user): + print(String(describing: user) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/update-recovery.md b/docs/examples/account/update-recovery.md index 56f3de4..1fc3e8f 100644 --- a/docs/examples/account/update-recovery.md +++ b/docs/examples/account/update-recovery.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,7 +5,7 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.updateRecovery( userId: "[USER_ID]", secret: "[SECRET]", @@ -15,10 +14,9 @@ func main() { ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let token): + print(String(describing: token) } } } -``` \ No newline at end of file diff --git a/docs/examples/account/update-verification.md b/docs/examples/account/update-verification.md index 02c44ea..228517d 100644 --- a/docs/examples/account/update-verification.md +++ b/docs/examples/account/update-verification.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let account = Account(client: client) + let account = Account(client) account.updateVerification( userId: "[USER_ID]", secret: "[SECRET]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let token): + print(String(describing: token) } } } -``` \ No newline at end of file diff --git a/docs/examples/avatars/get-browser.md b/docs/examples/avatars/get-browser.md index 26c559e..6be1cad 100644 --- a/docs/examples/avatars/get-browser.md +++ b/docs/examples/avatars/get-browser.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let avatars = Avatars(client: client) + let avatars = Avatars(client) avatars.getBrowser( code: "aa" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/avatars/get-credit-card.md b/docs/examples/avatars/get-credit-card.md index 7764d12..71bc427 100644 --- a/docs/examples/avatars/get-credit-card.md +++ b/docs/examples/avatars/get-credit-card.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let avatars = Avatars(client: client) + let avatars = Avatars(client) avatars.getCreditCard( code: "amex" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/avatars/get-favicon.md b/docs/examples/avatars/get-favicon.md index e06c140..fb2b907 100644 --- a/docs/examples/avatars/get-favicon.md +++ b/docs/examples/avatars/get-favicon.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let avatars = Avatars(client: client) + let avatars = Avatars(client) avatars.getFavicon( url: "https://example.com" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/avatars/get-flag.md b/docs/examples/avatars/get-flag.md index 6761e86..b642171 100644 --- a/docs/examples/avatars/get-flag.md +++ b/docs/examples/avatars/get-flag.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let avatars = Avatars(client: client) + let avatars = Avatars(client) avatars.getFlag( code: "af" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/avatars/get-image.md b/docs/examples/avatars/get-image.md index 8e6a9ba..811a33b 100644 --- a/docs/examples/avatars/get-image.md +++ b/docs/examples/avatars/get-image.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let avatars = Avatars(client: client) + let avatars = Avatars(client) avatars.getImage( url: "https://example.com" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/avatars/get-initials.md b/docs/examples/avatars/get-initials.md index 8156049..f58c397 100644 --- a/docs/examples/avatars/get-initials.md +++ b/docs/examples/avatars/get-initials.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let avatars = Avatars(client: client) - avatars.getInitials( + let avatars = Avatars(client) + avatars.getInitials() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/avatars/get-q-r.md b/docs/examples/avatars/get-q-r.md index 6365124..f5a35ec 100644 --- a/docs/examples/avatars/get-q-r.md +++ b/docs/examples/avatars/get-q-r.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let avatars = Avatars(client: client) + let avatars = Avatars(client) avatars.getQR( text: "[TEXT]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/database/create-collection.md b/docs/examples/database/create-collection.md deleted file mode 100644 index d7d9425..0000000 --- a/docs/examples/database/create-collection.md +++ /dev/null @@ -1,24 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let database = Database(client: client) - database.createCollection( - name: "[NAME]", - read: [], - write: [], - rules: [] - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/database/create-document.md b/docs/examples/database/create-document.md index d01506d..5471c9d 100644 --- a/docs/examples/database/create-document.md +++ b/docs/examples/database/create-document.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let database = Database(client: client) + let database = Database(client) database.createDocument( collectionId: "[COLLECTION_ID]", data: ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let document): + print(String(describing: document) } } } -``` \ No newline at end of file diff --git a/docs/examples/database/delete-collection.md b/docs/examples/database/delete-collection.md deleted file mode 100644 index ea78707..0000000 --- a/docs/examples/database/delete-collection.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let database = Database(client: client) - database.deleteCollection( - collectionId: "[COLLECTION_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/database/delete-document.md b/docs/examples/database/delete-document.md index ad465bb..e81e068 100644 --- a/docs/examples/database/delete-document.md +++ b/docs/examples/database/delete-document.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let database = Database(client: client) + let database = Database(client) database.deleteDocument( collectionId: "[COLLECTION_ID]", documentId: "[DOCUMENT_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let ): + print(String(describing: ) } } } -``` \ No newline at end of file diff --git a/docs/examples/database/get-collection.md b/docs/examples/database/get-collection.md deleted file mode 100644 index 9264a8a..0000000 --- a/docs/examples/database/get-collection.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let database = Database(client: client) - database.getCollection( - collectionId: "[COLLECTION_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/database/get-document.md b/docs/examples/database/get-document.md index 09a4090..0f02176 100644 --- a/docs/examples/database/get-document.md +++ b/docs/examples/database/get-document.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let database = Database(client: client) + let database = Database(client) database.getDocument( collectionId: "[COLLECTION_ID]", documentId: "[DOCUMENT_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let document): + print(String(describing: document) } } } -``` \ No newline at end of file diff --git a/docs/examples/database/list-collections.md b/docs/examples/database/list-collections.md deleted file mode 100644 index d57463d..0000000 --- a/docs/examples/database/list-collections.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let database = Database(client: client) - database.listCollections( - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/database/list-documents.md b/docs/examples/database/list-documents.md index aa9245b..e6f663c 100644 --- a/docs/examples/database/list-documents.md +++ b/docs/examples/database/list-documents.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let database = Database(client: client) + let database = Database(client) database.listDocuments( collectionId: "[COLLECTION_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let documentList): + print(String(describing: documentList) } } } -``` \ No newline at end of file diff --git a/docs/examples/database/update-collection.md b/docs/examples/database/update-collection.md deleted file mode 100644 index 2d0203a..0000000 --- a/docs/examples/database/update-collection.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let database = Database(client: client) - database.updateCollection( - collectionId: "[COLLECTION_ID]", - name: "[NAME]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/database/update-document.md b/docs/examples/database/update-document.md index c4dcc6e..5399ddb 100644 --- a/docs/examples/database/update-document.md +++ b/docs/examples/database/update-document.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,7 +5,7 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let database = Database(client: client) + let database = Database(client) database.updateDocument( collectionId: "[COLLECTION_ID]", documentId: "[DOCUMENT_ID]", @@ -14,10 +13,9 @@ func main() { ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let document): + print(String(describing: document) } } } -``` \ No newline at end of file diff --git a/docs/examples/functions/create-execution.md b/docs/examples/functions/create-execution.md index 1130cb3..004aa4d 100644 --- a/docs/examples/functions/create-execution.md +++ b/docs/examples/functions/create-execution.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let functions = Functions(client: client) + let functions = Functions(client) functions.createExecution( functionId: "[FUNCTION_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let execution): + print(String(describing: execution) } } } -``` \ No newline at end of file diff --git a/docs/examples/functions/create-tag.md b/docs/examples/functions/create-tag.md deleted file mode 100644 index 5d70625..0000000 --- a/docs/examples/functions/create-tag.md +++ /dev/null @@ -1,23 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.createTag( - functionId: "[FUNCTION_ID]", - command: "[COMMAND]", - code: xnil - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/create.md b/docs/examples/functions/create.md deleted file mode 100644 index 47130e5..0000000 --- a/docs/examples/functions/create.md +++ /dev/null @@ -1,23 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.create( - name: "[NAME]", - execute: [], - env: "dotnet-3.1" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/delete-tag.md b/docs/examples/functions/delete-tag.md deleted file mode 100644 index 27f47e8..0000000 --- a/docs/examples/functions/delete-tag.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.deleteTag( - functionId: "[FUNCTION_ID]", - tagId: "[TAG_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/delete.md b/docs/examples/functions/delete.md deleted file mode 100644 index 9e602a3..0000000 --- a/docs/examples/functions/delete.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.delete( - functionId: "[FUNCTION_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/get-execution.md b/docs/examples/functions/get-execution.md index b9de00b..c46bb40 100644 --- a/docs/examples/functions/get-execution.md +++ b/docs/examples/functions/get-execution.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let functions = Functions(client: client) + let functions = Functions(client) functions.getExecution( functionId: "[FUNCTION_ID]", executionId: "[EXECUTION_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let execution): + print(String(describing: execution) } } } -``` \ No newline at end of file diff --git a/docs/examples/functions/get-tag.md b/docs/examples/functions/get-tag.md deleted file mode 100644 index 690dfbd..0000000 --- a/docs/examples/functions/get-tag.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.getTag( - functionId: "[FUNCTION_ID]", - tagId: "[TAG_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/get-usage.md b/docs/examples/functions/get-usage.md deleted file mode 100644 index a870e43..0000000 --- a/docs/examples/functions/get-usage.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.getUsage( - functionId: "[FUNCTION_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/get.md b/docs/examples/functions/get.md deleted file mode 100644 index 948ce9e..0000000 --- a/docs/examples/functions/get.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.get( - functionId: "[FUNCTION_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/list-executions.md b/docs/examples/functions/list-executions.md index 2df66ce..04c212b 100644 --- a/docs/examples/functions/list-executions.md +++ b/docs/examples/functions/list-executions.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let functions = Functions(client: client) + let functions = Functions(client) functions.listExecutions( functionId: "[FUNCTION_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let executionList): + print(String(describing: executionList) } } } -``` \ No newline at end of file diff --git a/docs/examples/functions/list-tags.md b/docs/examples/functions/list-tags.md deleted file mode 100644 index e23a1ec..0000000 --- a/docs/examples/functions/list-tags.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.listTags( - functionId: "[FUNCTION_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/list.md b/docs/examples/functions/list.md deleted file mode 100644 index 1e3fc34..0000000 --- a/docs/examples/functions/list.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.list( - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/update-tag.md b/docs/examples/functions/update-tag.md deleted file mode 100644 index a6c0d63..0000000 --- a/docs/examples/functions/update-tag.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.updateTag( - functionId: "[FUNCTION_ID]", - tag: "[TAG]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/functions/update.md b/docs/examples/functions/update.md deleted file mode 100644 index a8c0918..0000000 --- a/docs/examples/functions/update.md +++ /dev/null @@ -1,23 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let functions = Functions(client: client) - functions.update( - functionId: "[FUNCTION_ID]", - name: "[NAME]", - execute: [] - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-anti-virus.md b/docs/examples/health/get-anti-virus.md deleted file mode 100644 index 72f7e65..0000000 --- a/docs/examples/health/get-anti-virus.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getAntiVirus() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-cache.md b/docs/examples/health/get-cache.md deleted file mode 100644 index ec64fe4..0000000 --- a/docs/examples/health/get-cache.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getCache() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-d-b.md b/docs/examples/health/get-d-b.md deleted file mode 100644 index d59c50b..0000000 --- a/docs/examples/health/get-d-b.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getDB() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-queue-certificates.md b/docs/examples/health/get-queue-certificates.md deleted file mode 100644 index 3345d20..0000000 --- a/docs/examples/health/get-queue-certificates.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getQueueCertificates() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-queue-functions.md b/docs/examples/health/get-queue-functions.md deleted file mode 100644 index 21938eb..0000000 --- a/docs/examples/health/get-queue-functions.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getQueueFunctions() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-queue-logs.md b/docs/examples/health/get-queue-logs.md deleted file mode 100644 index ff2c19d..0000000 --- a/docs/examples/health/get-queue-logs.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getQueueLogs() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-queue-tasks.md b/docs/examples/health/get-queue-tasks.md deleted file mode 100644 index d322331..0000000 --- a/docs/examples/health/get-queue-tasks.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getQueueTasks() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-queue-usage.md b/docs/examples/health/get-queue-usage.md deleted file mode 100644 index 38827d4..0000000 --- a/docs/examples/health/get-queue-usage.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getQueueUsage() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-queue-webhooks.md b/docs/examples/health/get-queue-webhooks.md deleted file mode 100644 index 7bbcefa..0000000 --- a/docs/examples/health/get-queue-webhooks.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getQueueWebhooks() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-storage-local.md b/docs/examples/health/get-storage-local.md deleted file mode 100644 index 52ebeed..0000000 --- a/docs/examples/health/get-storage-local.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getStorageLocal() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get-time.md b/docs/examples/health/get-time.md deleted file mode 100644 index 232eaa1..0000000 --- a/docs/examples/health/get-time.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.getTime() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/health/get.md b/docs/examples/health/get.md deleted file mode 100644 index 2b41bd0..0000000 --- a/docs/examples/health/get.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let health = Health(client: client) - health.get() { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/locale/get-continents.md b/docs/examples/locale/get-continents.md index 0e7c287..a07fb10 100644 --- a/docs/examples/locale/get-continents.md +++ b/docs/examples/locale/get-continents.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let locale = Locale(client: client) + let locale = Locale(client) locale.getContinents() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let continentList): + print(String(describing: continentList) } } } -``` \ No newline at end of file diff --git a/docs/examples/locale/get-countries-e-u.md b/docs/examples/locale/get-countries-e-u.md index 8faf727..58517a0 100644 --- a/docs/examples/locale/get-countries-e-u.md +++ b/docs/examples/locale/get-countries-e-u.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let locale = Locale(client: client) + let locale = Locale(client) locale.getCountriesEU() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let countryList): + print(String(describing: countryList) } } } -``` \ No newline at end of file diff --git a/docs/examples/locale/get-countries-phones.md b/docs/examples/locale/get-countries-phones.md index 47d1e04..cc28ba4 100644 --- a/docs/examples/locale/get-countries-phones.md +++ b/docs/examples/locale/get-countries-phones.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let locale = Locale(client: client) + let locale = Locale(client) locale.getCountriesPhones() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let phoneList): + print(String(describing: phoneList) } } } -``` \ No newline at end of file diff --git a/docs/examples/locale/get-countries.md b/docs/examples/locale/get-countries.md index ac70007..b37cb0d 100644 --- a/docs/examples/locale/get-countries.md +++ b/docs/examples/locale/get-countries.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let locale = Locale(client: client) + let locale = Locale(client) locale.getCountries() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let countryList): + print(String(describing: countryList) } } } -``` \ No newline at end of file diff --git a/docs/examples/locale/get-currencies.md b/docs/examples/locale/get-currencies.md index b1dd305..a97e93e 100644 --- a/docs/examples/locale/get-currencies.md +++ b/docs/examples/locale/get-currencies.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let locale = Locale(client: client) + let locale = Locale(client) locale.getCurrencies() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let currencyList): + print(String(describing: currencyList) } } } -``` \ No newline at end of file diff --git a/docs/examples/locale/get-languages.md b/docs/examples/locale/get-languages.md index 22bd0eb..a236afc 100644 --- a/docs/examples/locale/get-languages.md +++ b/docs/examples/locale/get-languages.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let locale = Locale(client: client) + let locale = Locale(client) locale.getLanguages() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let languageList): + print(String(describing: languageList) } } } -``` \ No newline at end of file diff --git a/docs/examples/locale/get.md b/docs/examples/locale/get.md index 634da00..0d93de1 100644 --- a/docs/examples/locale/get.md +++ b/docs/examples/locale/get.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let locale = Locale(client: client) + let locale = Locale(client) locale.get() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let locale): + print(String(describing: locale) } } } -``` \ No newline at end of file diff --git a/docs/examples/projects/create-domain.md b/docs/examples/projects/create-domain.md deleted file mode 100644 index 64e360c..0000000 --- a/docs/examples/projects/create-domain.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.createDomain( - projectId: "[PROJECT_ID]", - domain: "" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/create-key.md b/docs/examples/projects/create-key.md deleted file mode 100644 index edd1503..0000000 --- a/docs/examples/projects/create-key.md +++ /dev/null @@ -1,23 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.createKey( - projectId: "[PROJECT_ID]", - name: "[NAME]", - scopes: [] - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/create-platform.md b/docs/examples/projects/create-platform.md deleted file mode 100644 index 4dce90a..0000000 --- a/docs/examples/projects/create-platform.md +++ /dev/null @@ -1,23 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.createPlatform( - projectId: "[PROJECT_ID]", - type: "web", - name: "[NAME]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/create-task.md b/docs/examples/projects/create-task.md deleted file mode 100644 index fa921a5..0000000 --- a/docs/examples/projects/create-task.md +++ /dev/null @@ -1,27 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.createTask( - projectId: "[PROJECT_ID]", - name: "[NAME]", - status: "play", - schedule: "", - security: xfalse, - httpMethod: "GET", - httpUrl: "https://example.com" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/create-webhook.md b/docs/examples/projects/create-webhook.md deleted file mode 100644 index 8b4c221..0000000 --- a/docs/examples/projects/create-webhook.md +++ /dev/null @@ -1,25 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.createWebhook( - projectId: "[PROJECT_ID]", - name: "[NAME]", - events: [], - url: "https://example.com", - security: xfalse - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/create.md b/docs/examples/projects/create.md deleted file mode 100644 index 09d53f8..0000000 --- a/docs/examples/projects/create.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.create( - name: "[NAME]", - teamId: "[TEAM_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/delete-domain.md b/docs/examples/projects/delete-domain.md deleted file mode 100644 index 83c835b..0000000 --- a/docs/examples/projects/delete-domain.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.deleteDomain( - projectId: "[PROJECT_ID]", - domainId: "[DOMAIN_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/delete-key.md b/docs/examples/projects/delete-key.md deleted file mode 100644 index c5688b5..0000000 --- a/docs/examples/projects/delete-key.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.deleteKey( - projectId: "[PROJECT_ID]", - keyId: "[KEY_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/delete-platform.md b/docs/examples/projects/delete-platform.md deleted file mode 100644 index c113f8d..0000000 --- a/docs/examples/projects/delete-platform.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.deletePlatform( - projectId: "[PROJECT_ID]", - platformId: "[PLATFORM_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/delete-task.md b/docs/examples/projects/delete-task.md deleted file mode 100644 index 07991b6..0000000 --- a/docs/examples/projects/delete-task.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.deleteTask( - projectId: "[PROJECT_ID]", - taskId: "[TASK_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/delete-webhook.md b/docs/examples/projects/delete-webhook.md deleted file mode 100644 index bdf506f..0000000 --- a/docs/examples/projects/delete-webhook.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.deleteWebhook( - projectId: "[PROJECT_ID]", - webhookId: "[WEBHOOK_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/delete.md b/docs/examples/projects/delete.md deleted file mode 100644 index 49d253c..0000000 --- a/docs/examples/projects/delete.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.delete( - projectId: "[PROJECT_ID]", - password: "[PASSWORD]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/get-domain.md b/docs/examples/projects/get-domain.md deleted file mode 100644 index a58d9c1..0000000 --- a/docs/examples/projects/get-domain.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.getDomain( - projectId: "[PROJECT_ID]", - domainId: "[DOMAIN_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/get-key.md b/docs/examples/projects/get-key.md deleted file mode 100644 index 8c70a0e..0000000 --- a/docs/examples/projects/get-key.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.getKey( - projectId: "[PROJECT_ID]", - keyId: "[KEY_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/get-platform.md b/docs/examples/projects/get-platform.md deleted file mode 100644 index 88a05b6..0000000 --- a/docs/examples/projects/get-platform.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.getPlatform( - projectId: "[PROJECT_ID]", - platformId: "[PLATFORM_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/get-task.md b/docs/examples/projects/get-task.md deleted file mode 100644 index 99ecd0c..0000000 --- a/docs/examples/projects/get-task.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.getTask( - projectId: "[PROJECT_ID]", - taskId: "[TASK_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/get-usage.md b/docs/examples/projects/get-usage.md deleted file mode 100644 index dbd2e7a..0000000 --- a/docs/examples/projects/get-usage.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.getUsage( - projectId: "[PROJECT_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/get-webhook.md b/docs/examples/projects/get-webhook.md deleted file mode 100644 index 03e5595..0000000 --- a/docs/examples/projects/get-webhook.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.getWebhook( - projectId: "[PROJECT_ID]", - webhookId: "[WEBHOOK_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/get.md b/docs/examples/projects/get.md deleted file mode 100644 index bab48dc..0000000 --- a/docs/examples/projects/get.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.get( - projectId: "[PROJECT_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/list-domains.md b/docs/examples/projects/list-domains.md deleted file mode 100644 index 2e12e6f..0000000 --- a/docs/examples/projects/list-domains.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.listDomains( - projectId: "[PROJECT_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/list-keys.md b/docs/examples/projects/list-keys.md deleted file mode 100644 index ef590b9..0000000 --- a/docs/examples/projects/list-keys.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.listKeys( - projectId: "[PROJECT_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/list-platforms.md b/docs/examples/projects/list-platforms.md deleted file mode 100644 index 8c9f164..0000000 --- a/docs/examples/projects/list-platforms.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.listPlatforms( - projectId: "[PROJECT_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/list-tasks.md b/docs/examples/projects/list-tasks.md deleted file mode 100644 index 19f5f53..0000000 --- a/docs/examples/projects/list-tasks.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.listTasks( - projectId: "[PROJECT_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/list-webhooks.md b/docs/examples/projects/list-webhooks.md deleted file mode 100644 index e0eac34..0000000 --- a/docs/examples/projects/list-webhooks.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.listWebhooks( - projectId: "[PROJECT_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/list.md b/docs/examples/projects/list.md deleted file mode 100644 index e2fcfa6..0000000 --- a/docs/examples/projects/list.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.list( - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-auth-limit.md b/docs/examples/projects/update-auth-limit.md deleted file mode 100644 index 4b4bd44..0000000 --- a/docs/examples/projects/update-auth-limit.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updateAuthLimit( - projectId: "[PROJECT_ID]", - limit: "" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-auth-status.md b/docs/examples/projects/update-auth-status.md deleted file mode 100644 index 73f877f..0000000 --- a/docs/examples/projects/update-auth-status.md +++ /dev/null @@ -1,23 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updateAuthStatus( - projectId: "[PROJECT_ID]", - method: "email-password", - status: xfalse - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-domain-verification.md b/docs/examples/projects/update-domain-verification.md deleted file mode 100644 index 1b5312f..0000000 --- a/docs/examples/projects/update-domain-verification.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updateDomainVerification( - projectId: "[PROJECT_ID]", - domainId: "[DOMAIN_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-key.md b/docs/examples/projects/update-key.md deleted file mode 100644 index c73de52..0000000 --- a/docs/examples/projects/update-key.md +++ /dev/null @@ -1,24 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updateKey( - projectId: "[PROJECT_ID]", - keyId: "[KEY_ID]", - name: "[NAME]", - scopes: [] - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-o-auth2.md b/docs/examples/projects/update-o-auth2.md deleted file mode 100644 index 5a9612e..0000000 --- a/docs/examples/projects/update-o-auth2.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updateOAuth2( - projectId: "[PROJECT_ID]", - provider: "amazon" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-platform.md b/docs/examples/projects/update-platform.md deleted file mode 100644 index f94bd07..0000000 --- a/docs/examples/projects/update-platform.md +++ /dev/null @@ -1,23 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updatePlatform( - projectId: "[PROJECT_ID]", - platformId: "[PLATFORM_ID]", - name: "[NAME]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-task.md b/docs/examples/projects/update-task.md deleted file mode 100644 index 1f8781e..0000000 --- a/docs/examples/projects/update-task.md +++ /dev/null @@ -1,28 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updateTask( - projectId: "[PROJECT_ID]", - taskId: "[TASK_ID]", - name: "[NAME]", - status: "play", - schedule: "", - security: xfalse, - httpMethod: "GET", - httpUrl: "https://example.com" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update-webhook.md b/docs/examples/projects/update-webhook.md deleted file mode 100644 index cd94482..0000000 --- a/docs/examples/projects/update-webhook.md +++ /dev/null @@ -1,26 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.updateWebhook( - projectId: "[PROJECT_ID]", - webhookId: "[WEBHOOK_ID]", - name: "[NAME]", - events: [], - url: "https://example.com", - security: xfalse - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/projects/update.md b/docs/examples/projects/update.md deleted file mode 100644 index 3c5d230..0000000 --- a/docs/examples/projects/update.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let projects = Projects(client: client) - projects.update( - projectId: "[PROJECT_ID]", - name: "[NAME]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/storage/create-file.md b/docs/examples/storage/create-file.md index a8ab178..de85d89 100644 --- a/docs/examples/storage/create-file.md +++ b/docs/examples/storage/create-file.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) + let storage = Storage(client) storage.createFile( - file: xnil + file: File(name: "image.jpg", buffer: yourByteBuffer) ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let file): + print(String(describing: file) } } } -``` \ No newline at end of file diff --git a/docs/examples/storage/delete-file.md b/docs/examples/storage/delete-file.md index ed06d6c..27f2ba5 100644 --- a/docs/examples/storage/delete-file.md +++ b/docs/examples/storage/delete-file.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) + let storage = Storage(client) storage.deleteFile( fileId: "[FILE_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let ): + print(String(describing: ) } } } -``` \ No newline at end of file diff --git a/docs/examples/storage/get-file-download.md b/docs/examples/storage/get-file-download.md index 1527383..4474c3d 100644 --- a/docs/examples/storage/get-file-download.md +++ b/docs/examples/storage/get-file-download.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) + let storage = Storage(client) storage.getFileDownload( fileId: "[FILE_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/storage/get-file-preview.md b/docs/examples/storage/get-file-preview.md index e289178..ac1afa2 100644 --- a/docs/examples/storage/get-file-preview.md +++ b/docs/examples/storage/get-file-preview.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) + let storage = Storage(client) storage.getFilePreview( fileId: "[FILE_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/storage/get-file-view.md b/docs/examples/storage/get-file-view.md index 17a3d3f..b04b203 100644 --- a/docs/examples/storage/get-file-view.md +++ b/docs/examples/storage/get-file-view.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) + let storage = Storage(client) storage.getFileView( fileId: "[FILE_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - print(result) // Resource URL + print(error.message) + case .success(let byteBuffer): + print(String(describing: byteBuffer) } } } -``` \ No newline at end of file diff --git a/docs/examples/storage/get-file.md b/docs/examples/storage/get-file.md index 188b9ab..cd9441d 100644 --- a/docs/examples/storage/get-file.md +++ b/docs/examples/storage/get-file.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) + let storage = Storage(client) storage.getFile( fileId: "[FILE_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let file): + print(String(describing: file) } } } -``` \ No newline at end of file diff --git a/docs/examples/storage/list-files.md b/docs/examples/storage/list-files.md index cbf53d9..934856d 100644 --- a/docs/examples/storage/list-files.md +++ b/docs/examples/storage/list-files.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) - storage.listFiles( + let storage = Storage(client) + storage.listFiles() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let fileList): + print(String(describing: fileList) } } } -``` \ No newline at end of file diff --git a/docs/examples/storage/update-file.md b/docs/examples/storage/update-file.md index 2c30ad0..75f66e5 100644 --- a/docs/examples/storage/update-file.md +++ b/docs/examples/storage/update-file.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,7 +5,7 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let storage = Storage(client: client) + let storage = Storage(client) storage.updateFile( fileId: "[FILE_ID]", read: [], @@ -14,10 +13,9 @@ func main() { ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let file): + print(String(describing: file) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/create-membership.md b/docs/examples/teams/create-membership.md index c6201ee..01b3e50 100644 --- a/docs/examples/teams/create-membership.md +++ b/docs/examples/teams/create-membership.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,7 +5,7 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.createMembership( teamId: "[TEAM_ID]", email: "email@example.com", @@ -15,10 +14,9 @@ func main() { ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let membership): + print(String(describing: membership) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/create.md b/docs/examples/teams/create.md index e2594b1..5c5360c 100644 --- a/docs/examples/teams/create.md +++ b/docs/examples/teams/create.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.create( name: "[NAME]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let team): + print(String(describing: team) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/delete-membership.md b/docs/examples/teams/delete-membership.md index 558d32a..9f3086b 100644 --- a/docs/examples/teams/delete-membership.md +++ b/docs/examples/teams/delete-membership.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.deleteMembership( teamId: "[TEAM_ID]", membershipId: "[MEMBERSHIP_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let ): + print(String(describing: ) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/delete.md b/docs/examples/teams/delete.md index 922a4d5..49f1155 100644 --- a/docs/examples/teams/delete.md +++ b/docs/examples/teams/delete.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.delete( teamId: "[TEAM_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let ): + print(String(describing: ) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/get-memberships.md b/docs/examples/teams/get-memberships.md index 7aca6c9..3597ce1 100644 --- a/docs/examples/teams/get-memberships.md +++ b/docs/examples/teams/get-memberships.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.getMemberships( teamId: "[TEAM_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let membershipList): + print(String(describing: membershipList) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/get.md b/docs/examples/teams/get.md index 6885cbe..93b0f77 100644 --- a/docs/examples/teams/get.md +++ b/docs/examples/teams/get.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,16 +5,15 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.get( teamId: "[TEAM_ID]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let team): + print(String(describing: team) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/list.md b/docs/examples/teams/list.md index 50b2fda..2131371 100644 --- a/docs/examples/teams/list.md +++ b/docs/examples/teams/list.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,14 +5,13 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) - teams.list( + let teams = Teams(client) + teams.list() { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let teamList): + print(String(describing: teamList) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/update-membership-roles.md b/docs/examples/teams/update-membership-roles.md index 5b9f8ae..43d0db9 100644 --- a/docs/examples/teams/update-membership-roles.md +++ b/docs/examples/teams/update-membership-roles.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,7 +5,7 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.updateMembershipRoles( teamId: "[TEAM_ID]", membershipId: "[MEMBERSHIP_ID]", @@ -14,10 +13,9 @@ func main() { ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let membership): + print(String(describing: membership) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/update-membership-status.md b/docs/examples/teams/update-membership-status.md index 7a74633..dc82da7 100644 --- a/docs/examples/teams/update-membership-status.md +++ b/docs/examples/teams/update-membership-status.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,7 +5,7 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.updateMembershipStatus( teamId: "[TEAM_ID]", membershipId: "[MEMBERSHIP_ID]", @@ -15,10 +14,9 @@ func main() { ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let membership): + print(String(describing: membership) } } } -``` \ No newline at end of file diff --git a/docs/examples/teams/update.md b/docs/examples/teams/update.md index 6012cb4..a0822e8 100644 --- a/docs/examples/teams/update.md +++ b/docs/examples/teams/update.md @@ -1,4 +1,3 @@ -```swift import Appwrite func main() { @@ -6,17 +5,16 @@ func main() { .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint .setProject("5df5acd0d48c2") // Your project ID - let teams = Teams(client: client) + let teams = Teams(client) teams.update( teamId: "[TEAM_ID]", name: "[NAME]" ) { result in switch result { case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) + print(error.message) + case .success(let team): + print(String(describing: team) } } } -``` \ No newline at end of file diff --git a/docs/examples/users/create.md b/docs/examples/users/create.md deleted file mode 100644 index 8e4425f..0000000 --- a/docs/examples/users/create.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.create( - email: "email@example.com", - password: "password" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/users/delete-sessions.md b/docs/examples/users/delete-sessions.md deleted file mode 100644 index 22ff8bf..0000000 --- a/docs/examples/users/delete-sessions.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.deleteSessions( - userId: "[USER_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/users/delete.md b/docs/examples/users/delete.md deleted file mode 100644 index b66d859..0000000 --- a/docs/examples/users/delete.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.delete( - userId: "[USER_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/users/get-logs.md b/docs/examples/users/get-logs.md deleted file mode 100644 index 5c2bfae..0000000 --- a/docs/examples/users/get-logs.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.getLogs( - userId: "[USER_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/users/get-prefs.md b/docs/examples/users/get-prefs.md deleted file mode 100644 index 27e64bc..0000000 --- a/docs/examples/users/get-prefs.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.getPrefs( - userId: "[USER_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/users/get-sessions.md b/docs/examples/users/get-sessions.md deleted file mode 100644 index fa4d63b..0000000 --- a/docs/examples/users/get-sessions.md +++ /dev/null @@ -1,21 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.getSessions( - userId: "[USER_ID]" - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/users/list.md b/docs/examples/users/list.md deleted file mode 100644 index c413797..0000000 --- a/docs/examples/users/list.md +++ /dev/null @@ -1,19 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.list( - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/docs/examples/users/update-status.md b/docs/examples/users/update-status.md deleted file mode 100644 index a140756..0000000 --- a/docs/examples/users/update-status.md +++ /dev/null @@ -1,22 +0,0 @@ -```swift -import Appwrite - -func main() { - let client = Client() - .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint - .setProject("5df5acd0d48c2") // Your project ID - - let users = Users(client: client) - users.updateStatus( - userId: "[USER_ID]", - status: 1 - ) { result in - switch result { - case .failure(let error): - print(error) - case .success(let response): - let json = response.body!.readString(length: response.body!.readableBytes) - } - } -} -``` \ No newline at end of file diff --git a/example-swiftui/Example.xcodeproj/project.pbxproj b/example-swiftui/Example.xcodeproj/project.pbxproj index ae94209..a17b1a5 100644 --- a/example-swiftui/Example.xcodeproj/project.pbxproj +++ b/example-swiftui/Example.xcodeproj/project.pbxproj @@ -9,12 +9,19 @@ /* Begin PBXBuildFile section */ 1D0E30BC26B9430D002ECB40 /* ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0E30BB26B9430D002ECB40 /* ExampleApp.swift */; }; 1D0E30BD26B9430D002ECB40 /* ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0E30BB26B9430D002ECB40 /* ExampleApp.swift */; }; + 1D34C2532702E4A000D1DA8D /* ExampleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D34C2522702E4A000D1DA8D /* ExampleViewModel.swift */; }; + 1D34C2552702E4B500D1DA8D /* ExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D34C2542702E4B500D1DA8D /* ExampleView.swift */; }; 1D43900826FC8B2500C71E3E /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D43900726FC8B2500C71E3E /* ImagePicker.swift */; }; 1DC4093C26BA74470025A85C /* Appwrite in Frameworks */ = {isa = PBXBuildFile; productRef = 1DC4093B26BA74470025A85C /* Appwrite */; }; 1DC4093E26BA744D0025A85C /* Appwrite in Frameworks */ = {isa = PBXBuildFile; productRef = 1DC4093D26BA744D0025A85C /* Appwrite */; }; + 2358B1EE270AC9DC0016EFBA /* ExampleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D34C2522702E4A000D1DA8D /* ExampleViewModel.swift */; }; + 2358B1EF270AC9E30016EFBA /* ExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D34C2542702E4B500D1DA8D /* ExampleView.swift */; }; + 2358B1F0270AC9E80016EFBA /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D43900726FC8B2500C71E3E /* ImagePicker.swift */; }; + 23DDF5932709A457006EFAFA /* ImagePicker+iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23DDF5922709A457006EFAFA /* ImagePicker+iOS.swift */; }; + 23DDF5952709A46A006EFAFA /* ImagePicker+macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23DDF5942709A46A006EFAFA /* ImagePicker+macOS.swift */; }; + 23DDF598270AC2DA006EFAFA /* OSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23DDF597270AC2DA006EFAFA /* OSImage.swift */; }; + 23DDF599270AC2DA006EFAFA /* OSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23DDF597270AC2DA006EFAFA /* OSImage.swift */; }; 4B11518505BC6CF6BEBD216B /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B11557E0F213BC84ED01382 /* Tests_iOS.swift */; }; - 4B115325C5629636F758D520 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B115ABD18947485CC1B05F2 /* ContentView.swift */; }; - 4B11539FB91C8837DCF9E86C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B115ABD18947485CC1B05F2 /* ContentView.swift */; }; 4B1153AF12216F7E7AC0CC99 /* Tests_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B11562301B29DB7DF72AE29 /* Tests_macOS.swift */; }; 4B115544F254539A96D47868 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B115883E8645C18835765B2 /* Assets.xcassets */; }; 4B1157C67CF5E569FBCB65DD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B115883E8645C18835765B2 /* Assets.xcassets */; }; @@ -40,8 +47,13 @@ /* Begin PBXFileReference section */ 1D0E30BB26B9430D002ECB40 /* ExampleApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleApp.swift; sourceTree = ""; }; + 1D34C2522702E4A000D1DA8D /* ExampleViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleViewModel.swift; sourceTree = ""; }; + 1D34C2542702E4B500D1DA8D /* ExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleView.swift; sourceTree = ""; }; 1D43900726FC8B2500C71E3E /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; 1DC4093A26BA73C50025A85C /* swift-client */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "swift-client"; path = "../../../examples/swift-client"; sourceTree = ""; }; + 23DDF5922709A457006EFAFA /* ImagePicker+iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ImagePicker+iOS.swift"; sourceTree = ""; }; + 23DDF5942709A46A006EFAFA /* ImagePicker+macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ImagePicker+macOS.swift"; sourceTree = ""; }; + 23DDF597270AC2DA006EFAFA /* OSImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSImage.swift; sourceTree = ""; }; 4B11505C9899942E695B59FF /* test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4B115338FA3067342367ADA9 /* Keyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keyboard.swift; sourceTree = ""; }; 4B11555C2BF19042AB9E45DB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; @@ -49,7 +61,6 @@ 4B11562301B29DB7DF72AE29 /* Tests_macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_macOS.swift; sourceTree = ""; }; 4B115883E8645C18835765B2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4B1159CEF53EC1ED2744C870 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; - 4B115ABD18947485CC1B05F2 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 4B115D1FE1A2FDEB30700CA6 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; }; 4B115D7F73BEBBFC0952D71E /* Tests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 4B115D8A84F1369173AA102E /* Tests macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -99,6 +110,14 @@ name = Frameworks; sourceTree = ""; }; + 23DDF596270AC2B7006EFAFA /* Image */ = { + isa = PBXGroup; + children = ( + 23DDF597270AC2DA006EFAFA /* OSImage.swift */, + ); + path = Image; + sourceTree = ""; + }; 4B1152396B94D0F596CEBB52 = { isa = PBXGroup; children = ( @@ -116,11 +135,12 @@ 4B11566FD1E1FA1ABD88E438 /* Shared */ = { isa = PBXGroup; children = ( + 23DDF596270AC2B7006EFAFA /* Image */, 1D0E30BB26B9430D002ECB40 /* ExampleApp.swift */, 4B115883E8645C18835765B2 /* Assets.xcassets */, - 4B115ABD18947485CC1B05F2 /* ContentView.swift */, - 4B115338FA3067342367ADA9 /* Keyboard.swift */, 1D43900726FC8B2500C71E3E /* ImagePicker.swift */, + 1D34C2522702E4A000D1DA8D /* ExampleViewModel.swift */, + 1D34C2542702E4B500D1DA8D /* ExampleView.swift */, ); path = Shared; sourceTree = ""; @@ -139,6 +159,7 @@ children = ( 4B115EF92A96C13057984C77 /* Info.plist */, 4B115D1FE1A2FDEB30700CA6 /* macOS.entitlements */, + 23DDF5942709A46A006EFAFA /* ImagePicker+macOS.swift */, ); path = macOS; sourceTree = ""; @@ -167,6 +188,8 @@ isa = PBXGroup; children = ( 4B11555C2BF19042AB9E45DB /* Info.plist */, + 4B115338FA3067342367ADA9 /* Keyboard.swift */, + 23DDF5922709A457006EFAFA /* ImagePicker+iOS.swift */, ); path = iOS; sourceTree = ""; @@ -324,8 +347,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2358B1F0270AC9E80016EFBA /* ImagePicker.swift in Sources */, + 2358B1EF270AC9E30016EFBA /* ExampleView.swift in Sources */, + 2358B1EE270AC9DC0016EFBA /* ExampleViewModel.swift in Sources */, 1D0E30BD26B9430D002ECB40 /* ExampleApp.swift in Sources */, - 4B115325C5629636F758D520 /* ContentView.swift in Sources */, + 23DDF5952709A46A006EFAFA /* ImagePicker+macOS.swift in Sources */, + 23DDF599270AC2DA006EFAFA /* OSImage.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -349,10 +376,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1D34C2532702E4A000D1DA8D /* ExampleViewModel.swift in Sources */, 1D0E30BC26B9430D002ECB40 /* ExampleApp.swift in Sources */, + 23DDF598270AC2DA006EFAFA /* OSImage.swift in Sources */, 1D43900826FC8B2500C71E3E /* ImagePicker.swift in Sources */, - 4B11539FB91C8837DCF9E86C /* ContentView.swift in Sources */, 4B115FDF5335FA3B14FAA66B /* Keyboard.swift in Sources */, + 1D34C2552702E4B500D1DA8D /* ExampleView.swift in Sources */, + 23DDF5932709A457006EFAFA /* ImagePicker+iOS.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/example-swiftui/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/example-swiftui/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 7ec476c..0000000 --- a/example-swiftui/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,70 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "async-http-client", - "repositoryURL": "https://github.com/swift-server/async-http-client.git", - "state": { - "branch": null, - "revision": "8e4d51908dd49272667126403bf977c5c503f78f", - "version": "1.5.0" - } - }, - { - "package": "swift-log", - "repositoryURL": "https://github.com/apple/swift-log.git", - "state": { - "branch": null, - "revision": "5d66f7ba25daf4f94100e7022febf3c75e37a6c7", - "version": "1.4.2" - } - }, - { - "package": "swift-nio", - "repositoryURL": "https://github.com/apple/swift-nio.git", - "state": { - "branch": null, - "revision": "fb48bdd8279799f655da5f8b4e0a21430eca6012", - "version": "2.32.3" - } - }, - { - "package": "swift-nio-extras", - "repositoryURL": "https://github.com/apple/swift-nio-extras.git", - "state": { - "branch": null, - "revision": "f72c4688f89c28502105509186eadc49a49cb922", - "version": "1.10.0" - } - }, - { - "package": "swift-nio-http2", - "repositoryURL": "https://github.com/apple/swift-nio-http2.git", - "state": { - "branch": null, - "revision": "dbfc8fcd1a0cc4d7254a060501120d378e91f16c", - "version": "1.18.3" - } - }, - { - "package": "swift-nio-ssl", - "repositoryURL": "https://github.com/apple/swift-nio-ssl.git", - "state": { - "branch": null, - "revision": "044f90dfa0a7015446b40f5e578b06343ae1affe", - "version": "2.16.0" - } - }, - { - "package": "swift-nio-transport-services", - "repositoryURL": "https://github.com/apple/swift-nio-transport-services.git", - "state": { - "branch": null, - "revision": "39587bceccda72780e2a8a8c5e857e42a9df2fa8", - "version": "1.11.0" - } - } - ] - }, - "version": 1 -} diff --git a/example-swiftui/Shared/ContentView.swift b/example-swiftui/Shared/ContentView.swift deleted file mode 100644 index 747360b..0000000 --- a/example-swiftui/Shared/ContentView.swift +++ /dev/null @@ -1,171 +0,0 @@ -// -// ContentView.swift -// Shared -// -// Created by Jake Barnby on 3/08/21. -// -// - -import SwiftUI -import Appwrite -import NIO - -let host = "http://192.168.20.6:80/v1" -let projectId = "613b18dabf74a" - -let client = Client() - .setEndpoint(host) - .setProject(projectId) - -struct ContentView: View { - - let account = Account(client: client) - let storage = Storage(client: client) - let realtime = Realtime(client: client) - - @State var username: String = "test@test.test" - @State var password: String = "password" - @State var fileId: String = "614c1f5864841" - @State var collectionId: String = "6149afd52ce3b" - - @State private var isShowPhotoLibrary = false - @State private var imageToUpload = UIImage() - @State private var response: String = "" - @State private var downloadedImage: Image? = nil - - @ObservedObject var keyboard: Keyboard = .init() - - var body: some View { - - VStack(spacing: 8) { - - downloadedImage? - .resizable() - .aspectRatio(contentMode: .fit) - .frame(height: 200) - - TextEditor(text: $response) - .padding() - .padding(.bottom, keyboard.height) - .edgesIgnoringSafeArea(keyboard.height > 0 ? .bottom : []) - - Button("Login") { - login() - } - - Button("Login with Facebook") { - loginWithFacebook() - } - - Button("Register") { - register() - } - - Button("Download image") { - download() - } - - Button("Upload image") { - self.isShowPhotoLibrary = true - } - - Button("Subscribe") { - subscribe() - } - } - .sheet(isPresented: $isShowPhotoLibrary) { - ImagePicker(sourceType: .photoLibrary, selectedImage: self.$imageToUpload) - } - .onChange(of: imageToUpload) { img in - upload(image: img) - } - .registerOAuthHandler() - } - - func register() { - account.create(username, password) { result in - switch result { - case .failure(let error): self.response = error.message - case .success(var response): self.response = response.body!.readString(length: response.body!.readableBytes) ?? "" - } - } - } - - func login() { - account.createSession(username, password) { result in - switch result { - case .failure(let error): self.response = error.message - case .success(var response): self.response = response.body!.readString(length: response.body!.readableBytes) ?? "" - } - } - } - - 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 response): self.response = response.description - } - } - } - - func download() { - storage.getFileDownload(fileId) { result in - switch result { - case .failure(let error): - print(error) - case .success(var response): - downloadedImage = Image(uiImage: UIImage( - data: response.body!.readData( - length: response.body!.readableBytes - )! - )!) - } - } - } - - func upload(image: UIImage) { - let imageBuffer = ByteBufferAllocator() - .buffer(data: image.jpegData(compressionQuality: 1)!) - - let file = File( - name: "file.png", - buffer: imageBuffer - ) - - storage.createFile(file) { result in - switch result { - case .failure(let error): - print(error) - case .success(var response): - self.response = response.body!.readString(length: response.body!.readableBytes) ?? "" - } - } - } - - func subscribe() { - _ = realtime.subscribe(channels: ["collections.\(collectionId).documents"], payloadType: Test.self) { message in - print(String(describing: message)) - } - } -} - -class Test : Decodable { - public let name: String - public let description: String - - public init(name: String, description: String) { - self.name = name - self.description = description - } -} - -struct ContentView_Previews: PreviewProvider { - static var previews: some View { - ContentView() - } -} diff --git a/example-swiftui/Shared/ExampleApp.swift b/example-swiftui/Shared/ExampleApp.swift index 905ea96..19c5592 100644 --- a/example-swiftui/Shared/ExampleApp.swift +++ b/example-swiftui/Shared/ExampleApp.swift @@ -1,18 +1,12 @@ -// -// testApp.swift -// Shared -// -// Created by Jake Barnby on 3/08/21. -// -// - import SwiftUI +import Appwrite +import NIO @main struct ExampleApp: App { var body: some Scene { WindowGroup { - ContentView() + ExampleView(viewModel: ExampleView.ViewModel()) } } } diff --git a/example-swiftui/Shared/ExampleView.swift b/example-swiftui/Shared/ExampleView.swift new file mode 100644 index 0000000..801cb0c --- /dev/null +++ b/example-swiftui/Shared/ExampleView.swift @@ -0,0 +1,68 @@ +import SwiftUI +import Appwrite +import NIO + +struct ExampleView: View { + + @ObservedObject var viewModel: ViewModel + + @State var imageToUpload = OSImage() + + var body: some View { + + VStack(spacing: 8) { + + viewModel.downloadedImage? + .resizable() + .aspectRatio(contentMode: .fit) + .frame(height: 200) + + TextEditor(text: $viewModel.response) + .padding() + + Button("Login") { + viewModel.login() + } + + Button("Login with Facebook") { + viewModel.loginWithFacebook() + } + + Button("Register") { + viewModel.register() + } + + Button("Download image") { + viewModel.download() + } + + Button("Upload image") { + viewModel.isShowPhotoLibrary = true + } + + Button("Subscribe") { + viewModel.subscribe() + } + } + .onChange(of: viewModel.isShowPhotoLibrary) { showing in + #if os(macOS) + ImagePicker.present() + #endif + } + .sheet(isPresented: $viewModel.isShowPhotoLibrary) { + #if !os(macOS) + ImagePicker(selectedImage: $imageToUpload) + #endif + } + .onChange(of: imageToUpload) { img in + viewModel.upload(image: img) + } + .registerOAuthHandler() + } +} + +struct ExampleView_Previews: PreviewProvider { + static var previews: some View { + ExampleView(viewModel: ExampleView.ViewModel()) + } +} diff --git a/example-swiftui/Shared/ExampleViewModel.swift b/example-swiftui/Shared/ExampleViewModel.swift new file mode 100644 index 0000000..ac79ff9 --- /dev/null +++ b/example-swiftui/Shared/ExampleViewModel.swift @@ -0,0 +1,118 @@ +import Foundation +import SwiftUI +import Appwrite +import NIO + +let host = "https://localhost/v1" +let projectId = "60f6a0d6e2a52" + +extension ExampleView { + + class ViewModel : ObservableObject { + + let client = Client() + .setEndpoint(host) + .setProject(projectId) + + lazy var account = Account(client) + lazy var storage = Storage(client) + lazy var realtime = Realtime(client) + + @Published var downloadedImage: Image? = nil + + @Published public var username: String = "test@test.test" + @Published public var password: String = "password" + @Published public var fileId: String = "60f7a0178c3e5" + @Published public var collectionId: String = "6155742223662" + @Published public var isShowPhotoLibrary = false + @Published public var response: String = "" + + func register() { + account.create(email: username, password: password) { result in + DispatchQueue.main.async { + switch result { + case .failure(let error): + self.response = error.message + case .success(let response): + self.response = response.email + } + } + } + + + } + + func login() { + account.createSession(email: username, password: password) { result in + DispatchQueue.main.async { + switch result { + case .failure(let error): + self.response = error.message + case .success(let response): + self.response = response.userId + } + } + } + } + + func loginWithFacebook() { + account.createOAuth2Session( + provider: "facebook", + success: "\(host)/auth/oauth2/success", + failure: "\(host)/auth/oauth2/failure" + ) { result in + switch result { + case .failure: self.response = "false" + case .success(let response): self.response = response.description + } + } + } + + func download() { + storage.getFileDownload(fileId: fileId) { result in + DispatchQueue.main.async { + switch result { + case .failure(let error): self.response = error.message + case .success(let response): + self.downloadedImage = Image(data: Data(buffer: response)) + } + } + } + } + + func upload(image: OSImage) { + let imageBuffer = ByteBufferAllocator() + .buffer(data: image.data) + + #if os(macOS) + let fileName = "file.tiff" + #else + let fileName = "file.png" + #endif + + let file = File( + name: fileName, + buffer: imageBuffer + ) + + storage.createFile(file: file) { result in + DispatchQueue.main.async { + switch result { + case .failure(let error): + self.response = error.message + case .success(let response): + self.response = response.name + } + } + } + } + + func subscribe() { + _ = realtime.subscribe(channels: ["collections.\(collectionId).documents"]) { response in + DispatchQueue.main.async { + self.response = String(describing: response.payload!) + } + } + } + } +} diff --git a/example-swiftui/Shared/Image/OSImage.swift b/example-swiftui/Shared/Image/OSImage.swift new file mode 100644 index 0000000..11b8d73 --- /dev/null +++ b/example-swiftui/Shared/Image/OSImage.swift @@ -0,0 +1,35 @@ +// +// OSImage.swift +// Example +// +// Created by Jake on 4/10/21. +// +import SwiftUI + +#if os(macOS) +import AppKit +public typealias OSImage = NSImage +#elseif os(iOS) || os(tvOS) || os(watchOS) +import UIKit +public typealias OSImage = UIImage +#endif + +extension Image { + public init(data: Data) { + #if os(macOS) + self.init(nsImage: NSImage(data: data)!) + #elseif os(iOS) || os(tvOS) || os(watchOS) + self.init(uiImage: UIImage(data: data)!) + #endif + } +} + +extension OSImage { + public var data: Data { + #if os(macOS) + return self.tiffRepresentation! + #elseif os(iOS) || os(tvOS) || os(watchOS) + return self.pngData()! + #endif + } +} diff --git a/example-swiftui/Shared/ImagePicker.swift b/example-swiftui/Shared/ImagePicker.swift new file mode 100644 index 0000000..827356f --- /dev/null +++ b/example-swiftui/Shared/ImagePicker.swift @@ -0,0 +1,7 @@ +import SwiftUI + +struct ImagePicker { + @Binding var selectedImage: OSImage + + @Environment(\.presentationMode) var presentationMode +} diff --git a/example-swiftui/Tests iOS/Tests_iOS.swift b/example-swiftui/Tests iOS/Tests_iOS.swift index 7b0c218..fe781c0 100644 --- a/example-swiftui/Tests iOS/Tests_iOS.swift +++ b/example-swiftui/Tests iOS/Tests_iOS.swift @@ -1,11 +1,3 @@ -// -// Tests_iOS.swift -// Tests iOS -// -// Created by Jake Barnby on 3/08/21. -// -// - import XCTest class Tests_iOS: XCTestCase { diff --git a/example-swiftui/Tests macOS/Tests_macOS.swift b/example-swiftui/Tests macOS/Tests_macOS.swift index f38b63f..79762cf 100644 --- a/example-swiftui/Tests macOS/Tests_macOS.swift +++ b/example-swiftui/Tests macOS/Tests_macOS.swift @@ -1,11 +1,3 @@ -// -// Tests_macOS.swift -// Tests macOS -// -// Created by Jake Barnby on 3/08/21. -// -// - import XCTest class Tests_macOS: XCTestCase { diff --git a/example-swiftui/iOS/ImagePicker+iOS.swift b/example-swiftui/iOS/ImagePicker+iOS.swift new file mode 100644 index 0000000..afa7316 --- /dev/null +++ b/example-swiftui/iOS/ImagePicker+iOS.swift @@ -0,0 +1,46 @@ +import UIKit +import SwiftUI + +extension ImagePicker : UIViewControllerRepresentable { + + var sourceType: UIImagePickerController.SourceType { + get { + return .photoLibrary + } + } + + func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIImagePickerController { + + let imagePicker = UIImagePickerController() + imagePicker.allowsEditing = false + imagePicker.sourceType = sourceType + imagePicker.delegate = context.coordinator + + return imagePicker + } + + func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext) { + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { + + var parent: ImagePicker + + init(_ parent: ImagePicker) { + self.parent = parent + } + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + + if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { + parent.selectedImage = image + } + + parent.presentationMode.wrappedValue.dismiss() + } + } +} diff --git a/example-swiftui/Shared/Keyboard.swift b/example-swiftui/iOS/Keyboard.swift similarity index 100% rename from example-swiftui/Shared/Keyboard.swift rename to example-swiftui/iOS/Keyboard.swift diff --git a/example-swiftui/macOS/ImagePicker+macOS.swift b/example-swiftui/macOS/ImagePicker+macOS.swift new file mode 100644 index 0000000..114c7e0 --- /dev/null +++ b/example-swiftui/macOS/ImagePicker+macOS.swift @@ -0,0 +1,28 @@ +import AppKit + +extension ImagePicker { + static func present() { + let dialog = NSOpenPanel(); + + dialog.title = "Choose an image" + dialog.showsResizeIndicator = true + dialog.showsHiddenFiles = false + dialog.allowsMultipleSelection = false + dialog.canChooseDirectories = false + dialog.allowedFileTypes = ["png", "jpg", "jpeg", "gif", "tiff"] + + if (dialog.runModal() == NSApplication.ModalResponse.OK) { + guard let result = dialog.url else { + return + } + + + // path contains the file path e.g + // /Users/ourcodeworld/Desktop/tiger.jpeg + + } else { + // User clicked on "Cancel" + return + } + } +} diff --git a/example-swiftui/macOS/macOS.entitlements b/example-swiftui/macOS/macOS.entitlements index f2ef3ae..40b639e 100644 --- a/example-swiftui/macOS/macOS.entitlements +++ b/example-swiftui/macOS/macOS.entitlements @@ -2,9 +2,13 @@ - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + com.apple.security.network.client + + com.apple.security.network.server + diff --git a/example-uikit/UIKitExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/example-uikit/UIKitExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 496a7cb..7764221 100644 --- a/example-uikit/UIKitExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/example-uikit/UIKitExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -37,15 +37,6 @@ "version": "1.10.0" } }, - { - "package": "swift-nio-http2", - "repositoryURL": "https://github.com/apple/swift-nio-http2.git", - "state": { - "branch": null, - "revision": "42bdcae4ac4913507a5ee7af963c559deb60d1fc", - "version": "1.18.2" - } - }, { "package": "swift-nio-ssl", "repositoryURL": "https://github.com/apple/swift-nio-ssl.git", @@ -63,15 +54,6 @@ "revision": "39587bceccda72780e2a8a8c5e857e42a9df2fa8", "version": "1.11.0" } - }, - { - "package": "Swockets", - "repositoryURL": "https://github.com/abnegate/swockets.git", - "state": { - "branch": "develop", - "revision": "d04d00e98f07355ab7a377a3ab1c969b5ff335dc", - "version": null - } } ] }, diff --git a/example-uikit/UIKitExample/AppDelegate.swift b/example-uikit/UIKitExample/AppDelegate.swift index ef9853d..597ee24 100644 --- a/example-uikit/UIKitExample/AppDelegate.swift +++ b/example-uikit/UIKitExample/AppDelegate.swift @@ -1,11 +1,3 @@ -// -// AppDelegate.swift -// UIKitExample -// -// Created by Jake Barnby on 10/08/21. -// -// - import Appwrite import UIKit diff --git a/example-uikit/UIKitExample/ImagePicker.swift b/example-uikit/UIKitExample/ImagePicker.swift index 6e1010a..0c0522d 100644 --- a/example-uikit/UIKitExample/ImagePicker.swift +++ b/example-uikit/UIKitExample/ImagePicker.swift @@ -1,7 +1,3 @@ -// -// Created by Jake Barnby on 6/09/21. -// - import UIKit public protocol ImagePickerDelegate: AnyObject { diff --git a/example-uikit/UIKitExample/SceneDelegate.swift b/example-uikit/UIKitExample/SceneDelegate.swift index b706f7a..525b434 100644 --- a/example-uikit/UIKitExample/SceneDelegate.swift +++ b/example-uikit/UIKitExample/SceneDelegate.swift @@ -1,10 +1,3 @@ -// -// SceneDelegate.swift -// UIKitExample -// -// Created by Jake Barnby on 10/08/21. -// -// import Appwrite import UIKit diff --git a/example-uikit/UIKitExample/ViewController.swift b/example-uikit/UIKitExample/ViewController.swift index d5d0fed..3cabb1e 100644 --- a/example-uikit/UIKitExample/ViewController.swift +++ b/example-uikit/UIKitExample/ViewController.swift @@ -1,15 +1,9 @@ -// -// ViewController.swift -// UIKitExample -// -// Created by Jake Barnby on 10/08/21. -// -// - import UIKit import NIO import Appwrite +let host = "https://demo.appwrite.io/v1" + class ViewController: UIViewController { @IBOutlet weak var text: UITextView! @@ -21,16 +15,15 @@ class ViewController: UIViewController { @IBOutlet weak var image: UIImageView! let client = Client() - .setEndpoint("http://192.168.20.6:80/v1") - .setProject("613b18dabf74a") - .setSelfSigned(true) + .setEndpoint(host) + .setProject("60f6a0d6e2a52") - let COLLECTION_ID = "6149afd52ce3b" + let COLLECTION_ID = "6155742223662" - lazy var account = Account(client: client) - lazy var storage = Storage(client: client) - lazy var realtime = Realtime(client: client) - lazy var database = Database(client: client) + lazy var account = Account(client) + lazy var storage = Storage(client) + lazy var realtime = Realtime(client) + lazy var database = Database(client) var picker: ImagePicker? @@ -49,7 +42,7 @@ class ViewController: UIViewController { disptch.enter() var string: String = "" - account.create("jake@appwrite.io", "password") { result in + account.create(email: "jake@appwrite.io", password: "password") { result in switch result { case .failure(let error): string = error.message case .success(var response): string = response.body!.readString(length: response.body!.readableBytes) ?? "" @@ -61,7 +54,7 @@ class ViewController: UIViewController { } @IBAction func loginClick(_ sender: Any) { - account.createSession("jake@appwrite.io", "password") { result in + account.createSession(email: "jake@appwrite.io", password: "password") { result in var string: String = "" switch result { @@ -78,9 +71,9 @@ class ViewController: UIViewController { @IBAction func loginWithFacebook(_ sender: UIButton) { account.createOAuth2Session( - "facebook", - "https://demo.appwrite.io/auth/oauth2/success", - "https://demo.appwrite.io/auth/oauth2/failure") { result in + 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 { @@ -96,7 +89,7 @@ class ViewController: UIViewController { } @IBAction func download(_ sender: Any) { - storage.getFileDownload("614afaf579352") { result in + storage.getFileDownload(fileId: "614afaf579352") { result in switch result { case .failure(let error): DispatchQueue.main.async { @@ -117,16 +110,21 @@ class ViewController: UIViewController { } @IBAction func subscribe(_ sender: Any) { - _ = realtime.subscribe(channels:["collections.\(COLLECTION_ID).documents"], payloadType: Room.self) { message in - print(message) + _ = realtime.subscribe(channel:"collections.\(COLLECTION_ID).documents") { message in + DispatchQueue.main.async { + self.text.text = String(describing: message) + } } } @IBAction func createDocument(_ sender: Any) { - database.createDocument(COLLECTION_ID, [ - "name": "Name \(Int.random(in: 0...Int.max))", - "description": "Description \(Int.random(in: 0...Int.max))" - ], ["*"], ["*"]) { result in + database.createDocument( + collectionId: COLLECTION_ID, + data: [ + "name": "Name \(Int.random(in: 0...Int.max))", + "description": "Description \(Int.random(in: 0...Int.max))" + ] + ) { result in var string: String = "" switch result { @@ -152,7 +150,7 @@ extension ViewController: ImagePickerDelegate { let file = File(name: "my_image.jpg", buffer: buffer) - storage.createFile(file, ["*"], ["*"]) { result in + storage.createFile(file: file) { result in switch result { case .failure(let error): output = error.message @@ -166,6 +164,3 @@ extension ViewController: ImagePickerDelegate { } } } - -class Room : Model { -}