Skip to content

Commit 57dcd3d

Browse files
committed
Release candidate for 1.5.x
1 parent e9094ec commit 57dcd3d

File tree

228 files changed

+6499
-642
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

228 files changed

+6499
-642
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2023 Appwrite (https://appwrite.io) and individual contributors.
1+
Copyright (c) 2024 Appwrite (https://appwrite.io) and individual contributors.
22
All rights reserved.
33

44
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Package.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,28 @@ let package = Package(
1313
products: [
1414
.library(
1515
name: "Appwrite",
16-
targets: ["Appwrite", "AppwriteModels", "JSONCodable"]
16+
targets: [
17+
"Appwrite",
18+
"AppwriteEnums",
19+
"AppwriteModels",
20+
"JSONCodable"
21+
]
1722
),
1823
],
1924
dependencies: [
2025
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.9.0"),
21-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.32.0")
26+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.32.0"),
27+
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", from: "10.4.0")
2228
],
2329
targets: [
2430
.target(
2531
name: "Appwrite",
2632
dependencies: [
2733
.product(name: "AsyncHTTPClient", package: "async-http-client"),
2834
.product(name: "NIOWebSocket", package: "swift-nio"),
35+
.product(name: "FirebaseMessaging", package: "firebase-ios-sdk"),
2936
"AppwriteModels",
37+
"AppwriteEnums",
3038
"JSONCodable"
3139
]
3240
),
@@ -36,6 +44,9 @@ let package = Package(
3644
"JSONCodable"
3745
]
3846
),
47+
.target(
48+
name: "AppwriteEnums"
49+
),
3950
.target(
4051
name: "JSONCodable"
4152
),

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
![Swift Package Manager](https://img.shields.io/github/v/release/appwrite/sdk-for-swift.svg?color=green&style=flat-square)
44
![License](https://img.shields.io/github/license/appwrite/sdk-for-swift.svg?style=flat-square)
5-
![Version](https://img.shields.io/badge/api%20version-1.4.12-blue.svg?style=flat-square)
5+
![Version](https://img.shields.io/badge/api%20version-1.4.13-blue.svg?style=flat-square)
66
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
77
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
88
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
99

10-
**This SDK is compatible with Appwrite server version 1.4.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-swift/releases).**
10+
**This SDK is compatible with Appwrite server version 1.5.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-swift/releases).**
1111

1212
> This is the Swift SDK for integrating with Appwrite from your Swift server-side code. If you're looking for the Apple SDK you should check [appwrite/sdk-for-apple](https://github.com/appwrite/sdk-for-apple)
1313
@@ -33,7 +33,7 @@ Add the package to your `Package.swift` dependencies:
3333

3434
```swift
3535
dependencies: [
36-
.package(url: "git@github.com:appwrite/sdk-for-swift.git", from: "4.1.0"),
36+
.package(url: "git@github.com:appwrite/sdk-for-swift.git", from: "5.0.0-rc.1"),
3737
],
3838
```
3939

Sources/Appwrite/Client.swift

Lines changed: 120 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import Foundation
66
import AsyncHTTPClient
77
@_exported import AppwriteModels
88

9+
typealias CookieListener = (_ existing: [String], _ new: [String]) -> Void
10+
911
let DASHDASH = "--"
1012
let CRLF = "\r\n"
1113

@@ -19,34 +21,35 @@ open class Client {
1921
open var endPointRealtime: String? = nil
2022

2123
open var headers: [String: String] = [
22-
"content-type": "",
24+
"content-type": "application/json",
2325
"x-sdk-name": "Swift",
2426
"x-sdk-platform": "server",
2527
"x-sdk-language": "swift",
26-
"x-sdk-version": "4.1.0",
27-
"X-Appwrite-Response-Format": "1.4.0"
28+
"x-sdk-version": "5.0.0-rc.1",
29+
"x-appwrite-response-format": "1.4.0"
2830
]
2931

30-
open var config: [String: String] = [:]
32+
internal var config: [String: String] = [:]
33+
34+
internal var selfSigned: Bool = false
3135

32-
open var selfSigned: Bool = false
36+
internal var http: HTTPClient
3337

34-
open var http: HTTPClient
38+
internal static var cookieListener: CookieListener? = nil
3539

36-
private static let boundaryChars =
37-
"abcdefghijklmnopqrstuvwxyz1234567890"
40+
private static let boundaryChars = "abcdefghijklmnopqrstuvwxyz1234567890"
3841

3942
private static let boundary = randomBoundary()
4043

41-
private static var eventLoopGroupProvider =
42-
HTTPClient.EventLoopGroupProvider.createNew
44+
private static var eventLoopGroupProvider = HTTPClient.EventLoopGroupProvider.singleton
4345

4446
// MARK: Methods
4547

4648
public init() {
4749
http = Client.createHTTP()
4850
addUserAgentHeader()
4951
addOriginHeader()
52+
NotificationHandler.shared.client = self
5053
}
5154

5255
private static func createHTTP(
@@ -149,6 +152,51 @@ open class Client {
149152
return self
150153
}
151154

155+
///
156+
/// Set Session
157+
///
158+
/// The user session to authenticate with
159+
///
160+
/// @param String value
161+
///
162+
/// @return Client
163+
///
164+
open func setSession(_ value: String) -> Client {
165+
config["session"] = value
166+
_ = addHeader(key: "X-Appwrite-Session", value: value)
167+
return self
168+
}
169+
170+
///
171+
/// Set ForwardedFor
172+
///
173+
/// The IP address of the client that made the request
174+
///
175+
/// @param String value
176+
///
177+
/// @return Client
178+
///
179+
open func setForwardedFor(_ value: String) -> Client {
180+
config["forwardedfor"] = value
181+
_ = addHeader(key: "X-Forwarded-For", value: value)
182+
return self
183+
}
184+
185+
///
186+
/// Set ForwardedUserAgent
187+
///
188+
/// The user agent string of the client that made the request
189+
///
190+
/// @param String value
191+
///
192+
/// @return Client
193+
///
194+
open func setForwardedUserAgent(_ value: String) -> Client {
195+
config["forwardeduseragent"] = value
196+
_ = addHeader(key: "X-Forwarded-User-Agent", value: value)
197+
return self
198+
}
199+
152200

153201
///
154202
/// Set self signed
@@ -196,6 +244,19 @@ open class Client {
196244
return self
197245
}
198246

247+
///
248+
/// Set push provider ID.
249+
///
250+
/// @param String endpoint
251+
///
252+
/// @return this
253+
///
254+
open func setPushProviderId(_ providerId: String) -> Client {
255+
NotificationHandler.shared.providerId = providerId
256+
257+
return self
258+
}
259+
199260
///
200261
/// Add header
201262
///
@@ -310,64 +371,56 @@ open class Client {
310371
withSink bufferSink: ((ByteBuffer) -> Void)? = nil,
311372
converter: ((Any) -> T)? = nil
312373
) async throws -> T {
313-
func complete(with response: HTTPClientResponse) async throws -> T {
314-
switch response.status.code {
315-
case 0..<400:
316-
if response.headers["Set-Cookie"].count > 0 {
317-
UserDefaults.standard.set(
318-
response.headers["Set-Cookie"],
319-
forKey: URL(string: request.url)!.host! + "-cookies"
320-
)
321-
}
322-
switch T.self {
323-
case is Bool.Type:
324-
return true as! T
325-
case is ByteBuffer.Type:
326-
return try await response.body.collect(upTo: Int.max) as! T
327-
default:
328-
let data = try await response.body.collect(upTo: Int.max)
329-
if data.readableBytes == 0 {
330-
return true as! T
331-
}
332-
let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
374+
let response = try await http.execute(
375+
request,
376+
timeout: .seconds(30)
377+
)
333378

334-
return converter?(dict!) ?? dict! as! T
335-
}
379+
switch response.status.code {
380+
case 0..<400:
381+
if response.headers["Set-Cookie"].count > 0 {
382+
let domain = URL(string: request.url)!.host!
383+
let existing = UserDefaults.standard.stringArray(forKey: domain)
384+
let new = response.headers["Set-Cookie"]
385+
386+
Client.cookieListener?(existing ?? [], new)
387+
388+
UserDefaults.standard.set(new, forKey: domain)
389+
}
390+
switch T.self {
391+
case is Bool.Type:
392+
return true as! T
393+
case is ByteBuffer.Type:
394+
return try await response.body.collect(upTo: Int.max) as! T
336395
default:
337-
var message = ""
338-
var data = try await response.body.collect(upTo: Int.max)
339-
var type = ""
340-
341-
do {
342-
let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
343-
344-
message = dict?["message"] as? String ?? response.status.reasonPhrase
345-
type = dict?["type"] as? String ?? ""
346-
} catch {
347-
message = data.readString(length: data.readableBytes)!
396+
let data = try await response.body.collect(upTo: Int.max)
397+
if data.readableBytes == 0 {
398+
return true as! T
348399
}
400+
let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
349401

350-
throw AppwriteError(
351-
message: message,
352-
code: Int(response.status.code),
353-
type: type
354-
)
402+
return converter?(dict!) ?? dict! as! T
355403
}
356-
}
404+
default:
405+
var message = ""
406+
var data = try await response.body.collect(upTo: Int.max)
407+
var type = ""
357408

358-
if bufferSink == nil {
359-
let response = try await http.execute(
360-
request,
361-
timeout: .seconds(30)
409+
do {
410+
let dict = try JSONSerialization.jsonObject(with: data) as? [String: Any]
411+
412+
message = dict?["message"] as? String ?? response.status.reasonPhrase
413+
type = dict?["type"] as? String ?? ""
414+
} catch {
415+
message = data.readString(length: data.readableBytes)!
416+
}
417+
418+
throw AppwriteError(
419+
message: message,
420+
code: Int(response.status.code),
421+
type: type
362422
)
363-
return try await complete(with: response)
364423
}
365-
366-
let response = try await http.execute(
367-
request,
368-
timeout: .seconds(30)
369-
)
370-
return try await complete(with: response)
371424
}
372425

373426
func chunkedUpload<T>(
@@ -426,7 +479,7 @@ open class Client {
426479
while offset < size {
427480
let slice = (input.data as! ByteBuffer).getSlice(at: offset, length: Client.chunkSize)
428481
?? (input.data as! ByteBuffer).getSlice(at: offset, length: Int(size - offset))
429-
482+
430483
params[paramName] = InputFile.fromBuffer(slice!, filename: input.filename, mimeType: input.mimeType)
431484
headers["content-range"] = "bytes \(offset)-\(min((offset + Client.chunkSize) - 1, size - 1))/\(size)"
432485

@@ -481,7 +534,12 @@ open class Client {
481534
|| param is [Bool: Any] {
482535
encodedParams[key] = param
483536
} else {
484-
encodedParams[key] = try! (param as! Encodable).toJson()
537+
let value = try! (param as! Encodable).toJson()
538+
539+
let range = value.index(value.startIndex, offsetBy: 1)..<value.index(value.endIndex, offsetBy: -1)
540+
let substring = value[range]
541+
542+
encodedParams[key] = substring
485543
}
486544
}
487545

@@ -618,24 +676,3 @@ extension Client {
618676
return device
619677
}
620678
}
621-
622-
extension Client {
623-
624-
public enum HTTPStatus: Int {
625-
case unknown = -1
626-
case ok = 200
627-
case created = 201
628-
case accepted = 202
629-
case movedPermanently = 301
630-
case found = 302
631-
case badRequest = 400
632-
case notAuthorized = 401
633-
case paymentRequired = 402
634-
case forbidden = 403
635-
case notFound = 404
636-
case methodNotAllowed = 405
637-
case notAcceptable = 406
638-
case internalServerError = 500
639-
case notImplemented = 501
640-
}
641-
}

Sources/Appwrite/Extensions/HTTPClientRequest+Cookies.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension HTTPClientRequest {
1717

1818
extension HTTPHeaders {
1919
public mutating func addDomainCookies(for domain: String) {
20-
guard let cookies = UserDefaults.standard.stringArray(forKey: "\(domain)-cookies") else {
20+
guard let cookies = UserDefaults.standard.stringArray(forKey: domain) else {
2121
return
2222
}
2323
for cookie in cookies {

0 commit comments

Comments
 (0)