Skip to content

feat: Apple SDK update for version 18.1.0#119

Merged
ChiragAgg5k merged 5 commits into
mainfrom
dev
Jun 8, 2026
Merged

feat: Apple SDK update for version 18.1.0#119
ChiragAgg5k merged 5 commits into
mainfrom
dev

Conversation

@ChiragAgg5k

@ChiragAgg5k ChiragAgg5k commented Jun 8, 2026

Copy link
Copy Markdown
Member

This PR contains updates to the Apple SDK for version 18.1.0.

@ChiragAgg5k ChiragAgg5k changed the title feat: Apple SDK update for version 18.1.0 feat: SDK update for version 18.1.0 Jun 8, 2026
@greptile-apps

greptile-apps Bot commented Jun 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR updates the Apple SDK to version 18.1.0, adding new User email metadata fields (emailCanonical, emailIsFree, emailIsDisposable, emailIsCorporate, emailIsCanonical), a new Membership.userAccessedAt field, and a sweeping change to send explicit X-Appwrite-Project and accept headers per-method across all service files (coinciding with the removal of the global header injection from setProject).

  • All service methods (Account, Databases, Functions, Graphql, Locale, Messaging, Presences, Storage, TablesDB, Teams) now explicitly set X-Appwrite-Project from client.config[\"project\"] and an appropriate accept header on every request.
  • Five new User email metadata fields are added as proper optionals with decodeIfPresent, and the Membership.userAccessedAt field is added as a non-optional String, meaning decoding will throw if the server omits this privacy-gated attribute.
  • A Client.swift fix correctly handles URL paths that already contain a ? when appending GET query parameters.

Confidence Score: 3/5

The PR introduces a runtime decode crash in Membership (non-optional field absent by default) and sends empty-string project headers when setProject is not called — both identified in prior review rounds and still unresolved.

The new User email fields and the Functions.swift changes are correctly implemented, and the query-string fix in Client.swift is sound. However, Membership.userAccessedAt is decoded as a required non-optional String even though the server only includes it when a team owner explicitly enables the privacy toggle — every membership response under default settings will throw a DecodingError at decode time. In addition, removing the addHeader call from setProject means any caller that forgets setProject will silently send X-Appwrite-Project: '' on every request rather than receiving a clear configuration error. These two regressions affect core data models and authentication on every request.

Sources/AppwriteModels/Membership.swift requires the userAccessedAt field to be made optional; Sources/Appwrite/Client.swift needs attention around the setProject/X-Appwrite-Project header strategy.

Important Files Changed

Filename Overview
Sources/AppwriteModels/Membership.swift Adds userAccessedAt as a non-optional String; this is an opt-in privacy field that is absent by default, so decoding will always throw for memberships with default privacy settings.
Sources/AppwriteModels/User.swift Adds five new email metadata fields correctly as optionals with decodeIfPresent and as? casts in from(map:); implementation is consistent and safe.
Sources/Appwrite/Client.swift Removes global X-Appwrite-Project header injection from setProject; per-method fallback sends empty string when project is not configured. Also fixes query string concatenation when path already contains a ?.
Sources/Appwrite/Services/Account.swift Consistently adds X-Appwrite-Project and accept: application/json headers to all response-returning methods; void DELETE methods correctly omit the accept header.
Sources/Appwrite/Services/Functions.swift createExecution now correctly uses client.call with accept: application/json; listExecutions and getExecution also updated with project/accept headers.
Sources/Appwrite/Services/Storage.swift createFile correctly retains multipart/form-data content-type while adding accept: application/json; other methods updated consistently.

Reviews (5): Last reviewed commit: "chore: update Apple SDK to 18.1.0" | Re-trigger Greptile

Comment thread Sources/Appwrite/Services/Functions.swift Outdated
Comment thread Sources/Appwrite/Services/Oauth2.swift Outdated
Comment on lines +39 to +42
let apiHeaders: [String: String] = [
"content-type": "application/json",
"accept": "application/json"
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 approve and reject omit the X-Appwrite-Project header

approve (line 39-42) and reject (line 234-237) pass the project ID only as a hardcoded URL query parameter (?project=...), while createGrant and getGrant send it via the X-Appwrite-Project header instead. If the consent-screen endpoints require both, or if the project interpolation in the URL resolves to an empty string (when client.config["project"] is nil), these calls will silently misidentify the project. If the query-param approach is intentional for these OAuth2 protocol endpoints, a comment explaining the asymmetry would help maintainers.

Comment on lines 109 to 112
open func setProject(_ value: String) -> Client {
config["project"] = value
_ = addHeader(key: "X-Appwrite-Project", value: value)
return self
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 setProject no longer adds the header globally; per-method fallback sends empty string

Previously setProject called addHeader(key: "X-Appwrite-Project", value: value) so the header was injected into every request automatically. That line was removed, and every service method now reads client.config["project"] ?? "". If a caller never invokes setProject, every request will now send X-Appwrite-Project: "" instead of omitting the header entirely. An empty-string project header will reach the server and may produce a misleading 404/401 rather than a clear "project not configured" error. Consider at minimum an assertion or a guard in setProject, or restoring the addHeader call and removing the per-method duplication.

@ChiragAgg5k ChiragAgg5k changed the title feat: SDK update for version 18.1.0 feat: Apple SDK update for version 18.1.0 Jun 8, 2026
/// Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.
public let mfa: Bool
/// Most recent access date in ISO 8601 format. Show this attribute by toggling membership privacy in the Console.
public let userAccessedAt: String

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 userAccessedAt decoded as non-optional, crashes when field is absent

The doc comment says "Show this attribute by toggling membership privacy in the Console" — unlike mfa, userName, etc., which say "Hide" (opt-out, present by default), userAccessedAt is opt-in and absent from the response unless the team owner explicitly enables it. Using try container.decode(String.self, forKey: .userAccessedAt) will throw DecodingError.keyNotFound for all memberships where the privacy setting is off (the default). Similarly, map["userAccessedAt"] as! String at line 165 will crash at runtime. This field should be String? with decodeIfPresent and a as? String cast in from(map:), mirroring how the new User email fields are handled.

@ChiragAgg5k ChiragAgg5k changed the title feat: Apple SDK update for version 18.1.0 feat: SDK update for version 18.1.0 Jun 8, 2026
@ChiragAgg5k ChiragAgg5k changed the title feat: SDK update for version 18.1.0 feat: Apple SDK update for version 18.1.0 Jun 8, 2026
Comment on lines 103 to 111
return try await client.chunkedUpload(
path: apiPath,
headers: apiHeaders,
params: apiParams,
converter: converter
headers: &apiHeaders,
params: &apiParams,
paramName: paramName,
idParamName: idParamName,
converter: converter,
onProgress: onProgress
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 paramName is undefined — compile error

paramName is passed to chunkedUpload at line 107 but is never declared in createExecution's scope. Compare with Storage.createFile, which declares let paramName = "file" immediately before the same call. The missing declaration means this file will not compile. Since createExecution has no actual file parameter (unlike storage uploads), it is unclear whether paramName should be "body" or whether the entire switch from client.call to client.chunkedUpload is intentional — chunkedUpload is designed for streaming large binary files in chunks, while the execution body field is a plain optional String.

@ChiragAgg5k ChiragAgg5k merged commit 8749341 into main Jun 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants