Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Examples/Example-iOS/Example-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
Expand Down Expand Up @@ -400,7 +400,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
Expand Down
26 changes: 17 additions & 9 deletions Examples/Example-iOS/Sources/DetailTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -328,18 +328,26 @@ class DetailTableViewController: UITableViewController {
}

self.listener?.didReceiveDataSyncEvent = { dataSyncEvent in
switch dataSyncEvent {
case let .entityCreated(entity), let .entityUpdated(entity):
print("The \(entity.className) entity \(entity.id) was created or updated at \(entity.updatedAt)")
print("Received on \(dataSyncEvent.channel) at \(dataSyncEvent.timetoken)")

switch dataSyncEvent.change {
case let .entityCreated(entityEvent), let .entityUpdated(entityEvent):
let entity = entityEvent.entity
print("The \(entity.className) \(entityEvent.kind) \(entity.id) was created or updated at \(entity.updatedAt)")
print("Its revision is \(entity.eTag) and it expires at \(entity.expiresAt)")
print("Payload: \(entity.payload ?? "none")")
case let .relationshipCreated(relationship), let .relationshipUpdated(relationship):
print("The \(relationship.className) relationship \(relationship.id) was created or updated")
case let .relationshipCreated(relationshipEvent), let .relationshipUpdated(relationshipEvent):
let relationship = relationshipEvent.relationship
print("The \(relationship.className) \(relationshipEvent.kind) \(relationship.id) was created or updated")
print("It connects entity \(relationship.entityAId) to entity \(relationship.entityBId)")
case let .entityDeleted(removed):
print("The \(removed.className) entity \(removed.id) was deleted at \(removed.deletedAt)")
case let .relationshipDeleted(removed):
print("The \(removed.className) relationship \(removed.id) was deleted at \(removed.deletedAt)")
case let .entityDeleted(entityEvent):
let removed = entityEvent.removed
print("The \(removed.className) \(entityEvent.kind) \(removed.id) was deleted at \(removed.deletedAt)")
case let .relationshipDeleted(relationshipEvent):
let removed = relationshipEvent.removed
print("The \(removed.className) \(relationshipEvent.kind) \(removed.id) was deleted at \(removed.deletedAt)")
case let .unknown(unknownEvent):
print("Unrecognized \(unknownEvent.type) change: \(unknownEvent.event)")
}
}

Expand Down
4 changes: 2 additions & 2 deletions PubNub.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@
35C6B6DD22F501780054F242 /* Encodable+PubNub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C6B6DC22F501780054F242 /* Encodable+PubNub.swift */; };
35C6B6E322F515760054F242 /* SubscribeRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350EFBD722C926C300FA33AA /* SubscribeRouter.swift */; };
35C6B6E422F516040054F242 /* subscription_mixed_success.json in Resources */ = {isa = PBXBuildFile; fileRef = 35C6B6DF22F513D80054F242 /* subscription_mixed_success.json */; };
DA7A5C000000000000000201 /* subscription_unknownMessageType_success.json in Resources */ = {isa = PBXBuildFile; fileRef = DA7A5C000000000000000200 /* subscription_unknownMessageType_success.json */; };
35C6B6E622F51A060054F242 /* AnyJSONType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C6B6E522F51A060054F242 /* AnyJSONType.swift */; };
35C829DC23147AC000F59D3C /* SubscriptionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C829DB23147AC000F59D3C /* SubscriptionState.swift */; };
35C8FDC625000BC80069E89E /* FileManagementRouterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35AE6A3525000AC700BBFA37 /* FileManagementRouterTests.swift */; };
Expand Down Expand Up @@ -635,6 +634,7 @@
DA7A5C00000000000000004C /* DataSyncQueryParameterAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7A5C00000000000000004D /* DataSyncQueryParameterAPITests.swift */; };
DA7A5C00000000000000004E /* DataSyncErrorAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7A5C00000000000000004F /* DataSyncErrorAPITests.swift */; };
DA7A5C000000000000000060 /* Subscribable+PubNub.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7A5C000000000000000061 /* Subscribable+PubNub.swift */; };
DA7A5C000000000000000201 /* subscription_unknownMessageType_success.json in Resources */ = {isa = PBXBuildFile; fileRef = DA7A5C000000000000000200 /* subscription_unknownMessageType_success.json */; };
DC1FB72D98DF046B1FA1EED0 /* subscription_dataSyncEntityDelete_success.json in Resources */ = {isa = PBXBuildFile; fileRef = F663C27813A8D0288A85B9E3 /* subscription_dataSyncEntityDelete_success.json */; };
F56167435CA49717E3E0A5A3 /* subscription_dataSyncUserUpdate_success.json in Resources */ = {isa = PBXBuildFile; fileRef = EB86FDD4F6AE4E75660509FA /* subscription_dataSyncUserUpdate_success.json */; };
FEECFED552025EE3D7897E0C /* subscription_dataSyncRelationshipUpdate_success.json in Resources */ = {isa = PBXBuildFile; fileRef = BCCCA408812B8BD920DE6401 /* subscription_dataSyncRelationshipUpdate_success.json */; };
Expand Down Expand Up @@ -1013,7 +1013,6 @@
35B6FBB122F357A7005EE490 /* publish_invalid_json.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = publish_invalid_json.json; sourceTree = "<group>"; };
35C6B6DC22F501780054F242 /* Encodable+PubNub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Encodable+PubNub.swift"; sourceTree = "<group>"; };
35C6B6DF22F513D80054F242 /* subscription_mixed_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscription_mixed_success.json; sourceTree = "<group>"; };
DA7A5C000000000000000200 /* subscription_unknownMessageType_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscription_unknownMessageType_success.json; sourceTree = "<group>"; };
35C6B6E522F51A060054F242 /* AnyJSONType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyJSONType.swift; sourceTree = "<group>"; };
35C829DB23147AC000F59D3C /* SubscriptionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionState.swift; sourceTree = "<group>"; };
35C8FDCA25003A9F0069E89E /* file_generateURL_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = file_generateURL_success.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1394,6 +1393,7 @@
DA7A5C00000000000000004D /* DataSyncQueryParameterAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataSyncQueryParameterAPITests.swift; sourceTree = "<group>"; };
DA7A5C00000000000000004F /* DataSyncErrorAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataSyncErrorAPITests.swift; sourceTree = "<group>"; };
DA7A5C000000000000000061 /* Subscribable+PubNub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Subscribable+PubNub.swift"; sourceTree = "<group>"; };
DA7A5C000000000000000200 /* subscription_unknownMessageType_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscription_unknownMessageType_success.json; sourceTree = "<group>"; };
DA7B5C000000000000000065 /* data-sync-users.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "data-sync-users.swift"; sourceTree = "<group>"; };
DA7B5C000000000000000066 /* data-sync-channels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "data-sync-channels.swift"; sourceTree = "<group>"; };
DA7B5C000000000000000067 /* data-sync-memberships.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "data-sync-memberships.swift"; sourceTree = "<group>"; };
Expand Down
43 changes: 30 additions & 13 deletions Snippets/ListenersOld/listeners-old.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,36 @@ listener.didReceiveBatchSubscription = { events in
}

case .dataSyncChanged(let dataSyncEvent):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please, could you add to PubNubDataSyncRelationship and PubNubDataSyncRemovedRelationship
classLevel: PubNubDataSyncClassLevel
and pass the decoded classLevel to them?

@jguz-pubnub jguz-pubnub Oct 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Relationship classes are not possible for extensions. This is the reason why there's no classLevel property in PubNubDataSyncRemovedRelationship and PubNubDataSyncRelationship. Am I missing something crucial here?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

They are not present in CRUD operation but present in subscribe event. Currently for Membership it is "Global " and for Relationships it is "SubKey". But never mind we can handle this. The thing is that Kotlin and JS already have it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ok, then I'll add it to

switch dataSyncEvent {
case let .entityCreated(entity):
print("Data Sync entity created: \(entity.id)")
case let .entityUpdated(entity):
print("Data Sync entity updated: \(entity.id)")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This comment is not related to this file.
JVM and JS deliver a valid DataSync event with an unrecognised metadata.event or metadata.type as PNUnknownDataSyncEventMessage. Could you add this?

Unknown result: the payload is a DataSync event (metadata.source == "data-sync", and metadata.event and metadata.type are present non-empty strings), but the pair isn't one Swift
handles. Examples: type: "space", or event: "expire" on type: "user".

Keep dropping: the pair is known but the payload is broken, e.g. a required data field is missing. JVM drops these too, so behaviour matches.

@jguz-pubnub jguz-pubnub Oct 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll take a look at that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will add PubNubDataSyncUnknownEvent and let you know when it's ready

case let .entityDeleted(entity):
print("Data Sync entity deleted: \(entity.id)")
case let .relationshipCreated(relationship):
print("Data Sync relationship created: \(relationship.id)")
case let .relationshipUpdated(relationship):
print("Data Sync relationship updated: \(relationship.id)")
case let .relationshipDeleted(relationship):
print("Data Sync relationship deleted: \(relationship.id)")
print("Received on \(dataSyncEvent.channel) at \(dataSyncEvent.timetoken)")

switch dataSyncEvent.change {
case let .entityCreated(entityEvent):
let entity = entityEvent.entity
print("Entity \(entity.id) was created.")
print("Entity kind: \(entityEvent.kind)")
case let .entityUpdated(entityEvent):
let entity = entityEvent.entity
print("Entity \(entity.id) was updated.")
print("Entity kind: \(entityEvent.kind)")
case let .entityDeleted(entityEvent):
let removedEntity = entityEvent.removed
print("Entity \(removedEntity.id) was deleted.")
print("Entity kind: \(entityEvent.kind)")
case let .relationshipCreated(relationshipEvent):
let relationship = relationshipEvent.relationship
print("Relationship \(relationship.id) was created.")
print("Relationship kind: \(relationshipEvent.kind)")
case let .relationshipUpdated(relationshipEvent):
let relationship = relationshipEvent.relationship
print("Relationship \(relationship.id) was updated.")
print("Relationship kind: \(relationshipEvent.kind)")
case let .relationshipDeleted(relationshipEvent):
let removedRelationship = relationshipEvent.removed
print("Relationship \(removedRelationship.id) was deleted.")
print("Relationship kind: \(relationshipEvent.kind)")
case let .unknown(unknownEvent):
// An object type or action this SDK version doesn't recognize
print("Unrecognized \(unknownEvent.type) change: \(unknownEvent.event)")
}
}
}
Expand Down
43 changes: 30 additions & 13 deletions Snippets/SubscribeNew/subscriptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,19 +201,36 @@ subscription.onAppContext = { appContextEvent in
// snippet.on-data-sync
// Add a listener to receive Data Sync entity and relationship events
dataSyncSubscription.onDataSync = { dataSyncEvent in
switch dataSyncEvent {
case let .entityCreated(entity):
print("Data Sync entity created: \(entity.id)")
case let .entityUpdated(entity):
print("Data Sync entity updated: \(entity.id)")
case let .entityDeleted(entity):
print("Data Sync entity deleted: \(entity.id)")
case let .relationshipCreated(relationship):
print("Data Sync relationship created: \(relationship.id)")
case let .relationshipUpdated(relationship):
print("Data Sync relationship updated: \(relationship.id)")
case let .relationshipDeleted(relationship):
print("Data Sync relationship deleted: \(relationship.id)")
print("Received on \(dataSyncEvent.channel) at \(dataSyncEvent.timetoken)")

switch dataSyncEvent.change {
case let .entityCreated(entityEvent):
let entity = entityEvent.entity
print("Entity \(entity.id) was created.")
print("Entity kind: \(entityEvent.kind)")
case let .entityUpdated(entityEvent):
let entity = entityEvent.entity
print("Entity \(entity.id) was updated.")
print("Entity kind: \(entityEvent.kind)")
case let .entityDeleted(entityEvent):
let removedEntity = entityEvent.removed
print("Entity \(removedEntity.id) was deleted.")
print("Entity kind: \(entityEvent.kind)")
case let .relationshipCreated(relationshipEvent):
let relationship = relationshipEvent.relationship
print("Relationship \(relationship.id) was created.")
print("Relationship kind: \(relationshipEvent.kind)")
case let .relationshipUpdated(relationshipEvent):
let relationship = relationshipEvent.relationship
print("Relationship \(relationship.id) was updated.")
print("Relationship kind: \(relationshipEvent.kind)")
case let .relationshipDeleted(relationshipEvent):
let removedRelationship = relationshipEvent.removed
print("Relationship \(removedRelationship.id) was deleted.")
print("Relationship kind: \(relationshipEvent.kind)")
case let .unknown(unknownEvent):
// An object type or action this SDK version doesn't recognize
print("Unrecognized \(unknownEvent.type) change: \(unknownEvent.event)")
}
}
// snippet.end
Expand Down
Loading
Loading