Skip to content

feat: Apple SDK update for version 17.1.0#112

Merged
ArnabChatterjee20k merged 12 commits into
mainfrom
dev
May 19, 2026
Merged

feat: Apple SDK update for version 17.1.0#112
ArnabChatterjee20k merged 12 commits into
mainfrom
dev

Conversation

@ArnabChatterjee20k

@ArnabChatterjee20k ArnabChatterjee20k commented May 18, 2026

Copy link
Copy Markdown
Member

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

What's Changed

  • Added: Realtime presences channel and RealtimePresence types for presence subscriptions
  • Added: Advisor and Presences services
  • Added: Insight, Presence, and Report models with list variants
  • Added: fusionauth, keycloak, and kick providers to OAuthProvider enum
  • Updated: X-Appwrite-Response-Format header to 1.9.5

@greptile-apps

greptile-apps Bot commented May 18, 2026

Copy link
Copy Markdown

Greptile Summary

This PR updates the Apple SDK to version 17.1.0, adding new Presence and Advisor (Reports/Insights) services, refactoring Realtime to use post-connect subscribe messages instead of URL query parameters, and fixing enum .rawValue serialization across Account, Avatars, Functions, and Storage services.

  • New Presences and Advisor services with correct typed-generic patterns; new Channel.presence() factory added.
  • toMap() fixed across Document, Row, Preferences, and Presence to use JSONSerialization.jsonObject instead of raw Foundation.Data.
  • User.from(map:) hashOptions conversion uses ?? [:] fallback that turns the optional field always non-nil; Document/Row from(map:) empty-dict fallback causes a try! crash for any T with required non-optional properties when the data key is absent.

Confidence Score: 3/5

The PR has two definite crash paths in the model layer that affect SDK users, on top of several concurrency issues from earlier review rounds that remain unresolved.

User.from(map:) silently drops the optional semantics of hashOptions making it always non-nil, and Document/Row from(map:) crash via try! for any strongly-typed T when the data key is absent from the response.

Sources/AppwriteModels/User.swift, Sources/AppwriteModels/Document.swift, Sources/AppwriteModels/Row.swift, Sources/Appwrite/Services/Realtime.swift

Important Files Changed

Filename Overview
Sources/AppwriteModels/User.swift Fixed hashOptions cast from [String: Any] to [String: AnyCodable], but the ?? [:] fallback makes the optional field always non-nil when absent from the server response, breaking its optional contract.
Sources/AppwriteModels/Document.swift Fixed toMap() Data serialization and improved from(map:) type handling, but the empty-dict fallback causes a try! crash for any T with required non-optional properties when the data key is absent.
Sources/AppwriteModels/Row.swift Same from(map:) empty-dict-fallback crash pattern as Document.swift.
Sources/AppwriteModels/Presence.swift New generic Presence model; toMap() improved, but from(map:) still has try! crash when metadata is absent and T has required properties (previously flagged).
Sources/Appwrite/Services/Realtime.swift Major refactor for presence and post-connect subscribe; subscriptionsSync queue added, but several concurrency issues remain (previously flagged).
Sources/Appwrite/Services/Presences.swift New Presences service with list/get/upsert/update/delete; straightforward implementation.
Sources/Appwrite/Services/Advisor.swift New Advisor service exposing listReports, getReport, listInsights, getInsight — clean, consistent with SDK patterns.
Sources/Appwrite/Client.swift New setCompression method and addHeader case-insensitive guard added; stale header issue when re-enabling compression (previously flagged).
Sources/AppwriteModels/InsightCTA.swift New model; from(map:) now correctly converts via mapValues, fixing the previously-flagged direct-cast crash.
Sources/AppwriteModels/Preferences.swift toMap() fixed to produce a deserialized JSON object instead of raw Data; from(map:) unchanged and correct.

Comments Outside Diff (1)

  1. Sources/AppwriteModels/Document.swift, line 99-115 (link)

    P1 try! crash for any T with non-optional required properties when data is absent or not a JSON object. The else branch falls back to an empty {}, and JSONDecoder throws keyNotFound for every required field — which try! converts to a process-terminating trap. The same pattern is present in Row.from(map:). A safe fix would be to use try? or propagate a thrown error instead of force-unwrapping.

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

Comment thread Sources/AppwriteModels/Presence.swift
Comment thread Sources/AppwriteModels/Presence.swift
Comment thread Sources/Appwrite/Services/Realtime.swift
Comment thread Sources/Appwrite/Services/Realtime.swift
private func createSocketLocked() async throws {
let hasPendingPresence: Bool = presenceSync.sync { pendingPresence != nil }
guard activeSubscriptions.count > 0 || hasPendingPresence else {
reconnect = false

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 Channels and queries are no longer included in the WebSocket URL

The new createSocketLocked constructs the URL with project=<id> only, dropping the channels[] and per-slot query parameters that were previously appended. Subscription data is now sent as a subscribe message after the connected event. If the Appwrite server still expects channels in the initial URL handshake, all realtime subscriptions will silently receive no events. Please confirm this matches the updated server-side protocol for 17.1.0. Does the Appwrite 17.1.0 server accept channel subscriptions via a post-connect subscribe WebSocket message rather than URL query parameters?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

expected and we follow this only

# Conflicts:
#	CHANGELOG.md
#	README.md
#	Sources/Appwrite/Client.swift
#	Sources/Appwrite/Services/Realtime.swift
Comment thread Sources/AppwriteModels/InsightCTA.swift
Comment thread Sources/Appwrite/Services/Realtime.swift Outdated
Comment thread Sources/Appwrite/Client.swift
Comment thread Sources/AppwriteModels/Presence.swift Outdated
password: map["password"] as? String,
hash: map["hash"] as? String,
hashOptions: map["hashOptions"] as? [String: AnyCodable],
hashOptions: (map["hashOptions"] as? [String: Any] ?? [:]).mapValues { AnyCodable($0) },

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 hashOptions loses its optional semantics. The ?? [:] fallback means hashOptions is always a non-nil empty dict when the key is absent from the server response, so any caller checking user.hashOptions != nil will now always see a truthy value. The correct fix chains ?.mapValues so the optional remains nil when the key is absent.

Suggested change
hashOptions: (map["hashOptions"] as? [String: Any] ?? [:]).mapValues { AnyCodable($0) },
hashOptions: (map["hashOptions"] as? [String: Any])?.mapValues { AnyCodable($0) },

@ArnabChatterjee20k ArnabChatterjee20k merged commit 7acef0c into main May 19, 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.

3 participants