Skip to content

Commit 51163d6

Browse files
authored
Add ETag support for setting Channel and User metadata (#201)
1 parent 5878413 commit 51163d6

File tree

8 files changed

+69
-23
lines changed

8 files changed

+69
-23
lines changed

.pubnub.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
---
22
name: swift
33
scm: github.com/pubnub/swift
4-
version: "8.2.5"
4+
version: "8.3.0"
55
schema: 1
66
changelog:
7+
- date: 2025-01-20
8+
version: 8.3.0
9+
changes:
10+
- type: feature
11+
text: "Add `ETag` support for setting Channel and User metadata."
712
- date: 2025-01-16
813
version: 8.2.5
914
changes:
@@ -648,7 +653,7 @@ sdks:
648653
- distribution-type: source
649654
distribution-repository: GitHub release
650655
package-name: PubNub
651-
location: https://github.com/pubnub/swift/archive/refs/tags/8.2.5.zip
656+
location: https://github.com/pubnub/swift/archive/refs/tags/8.3.0.zip
652657
supported-platforms:
653658
supported-operating-systems:
654659
macOS:

PubNub.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3999,7 +3999,7 @@
39993999
"@loader_path/Frameworks",
40004000
);
40014001
MACOSX_DEPLOYMENT_TARGET = 10.15;
4002-
MARKETING_VERSION = 8.2.5;
4002+
MARKETING_VERSION = 8.3.0;
40034003
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
40044004
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
40054005
MTL_FAST_MATH = YES;
@@ -4050,7 +4050,7 @@
40504050
"@loader_path/Frameworks",
40514051
);
40524052
MACOSX_DEPLOYMENT_TARGET = 10.15;
4053-
MARKETING_VERSION = 8.2.5;
4053+
MARKETING_VERSION = 8.3.0;
40544054
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
40554055
MTL_ENABLE_DEBUG_INFO = NO;
40564056
MTL_FAST_MATH = YES;
@@ -4158,7 +4158,7 @@
41584158
"@loader_path/Frameworks",
41594159
);
41604160
MACOSX_DEPLOYMENT_TARGET = 10.15;
4161-
MARKETING_VERSION = 8.2.5;
4161+
MARKETING_VERSION = 8.3.0;
41624162
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
41634163
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
41644164
MTL_FAST_MATH = YES;
@@ -4211,7 +4211,7 @@
42114211
"@loader_path/Frameworks",
42124212
);
42134213
MACOSX_DEPLOYMENT_TARGET = 10.15;
4214-
MARKETING_VERSION = 8.2.5;
4214+
MARKETING_VERSION = 8.3.0;
42154215
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
42164216
MTL_ENABLE_DEBUG_INFO = NO;
42174217
MTL_FAST_MATH = YES;
@@ -4332,7 +4332,7 @@
43324332
"@loader_path/Frameworks",
43334333
);
43344334
MACOSX_DEPLOYMENT_TARGET = 10.15;
4335-
MARKETING_VERSION = 8.2.5;
4335+
MARKETING_VERSION = 8.3.0;
43364336
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
43374337
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
43384338
MTL_FAST_MATH = YES;
@@ -4384,7 +4384,7 @@
43844384
"@loader_path/Frameworks",
43854385
);
43864386
MACOSX_DEPLOYMENT_TARGET = 10.15;
4387-
MARKETING_VERSION = 8.2.5;
4387+
MARKETING_VERSION = 8.3.0;
43884388
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
43894389
MTL_ENABLE_DEBUG_INFO = NO;
43904390
MTL_FAST_MATH = YES;
@@ -4864,7 +4864,7 @@
48644864
"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
48654865
);
48664866
MACOSX_DEPLOYMENT_TARGET = 10.15;
4867-
MARKETING_VERSION = 8.2.5;
4867+
MARKETING_VERSION = 8.3.0;
48684868
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14";
48694869
OTHER_CFLAGS = "$(inherited)";
48704870
OTHER_LDFLAGS = "$(inherited)";
@@ -4907,7 +4907,7 @@
49074907
"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
49084908
);
49094909
MACOSX_DEPLOYMENT_TARGET = 10.15;
4910-
MARKETING_VERSION = 8.2.5;
4910+
MARKETING_VERSION = 8.3.0;
49114911
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14";
49124912
OTHER_CFLAGS = "$(inherited)";
49134913
OTHER_LDFLAGS = "$(inherited)";

PubNubSwift.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'PubNubSwift'
3-
s.version = '8.2.5'
3+
s.version = '8.3.0'
44
s.homepage = 'https://github.com/pubnub/swift'
55
s.documentation_url = 'https://www.pubnub.com/docs/swift-native/pubnub-swift-sdk'
66
s.authors = { 'PubNub, Inc.' => 'support@pubnub.com' }

Sources/PubNub/APIs/Objects+PubNub.swift

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -537,24 +537,29 @@ public extension PubNub {
537537
///
538538
/// Set metadata for a User in the database, optionally including the custom data object for each.
539539
/// - Parameters:
540-
/// - user: The `PubNubUserMetadata` to set
540+
/// - metadata: The `PubNubUserMetadata` to set
541+
/// - ifMatchesEtag: The entity tag to be used for the `If-Match` HTTP header to enable conditional requests
541542
/// - include: Include respective additional fields in the response.
542543
/// - custom: Custom configuration overrides for this request
543544
/// - completion: The async `Result` of the method call
544545
/// - **Success**: The `PubNubUserMetadata` containing the set changes
545546
/// - **Failure**: An `Error` describing the failure
546547
func setUserMetadata(
547548
_ metadata: PubNubUserMetadata,
549+
ifMatchesEtag: String? = nil,
548550
include: UserIncludeFields = UserIncludeFields(),
549551
custom requestConfig: RequestConfiguration = RequestConfiguration(),
550552
completion: ((Result<PubNubUserMetadata, Error>) -> Void)?
551553
) {
554+
let customHeadersIfAny = if let entityTag = ifMatchesEtag {
555+
[Constant.ifMatchHeaderKey: entityTag]
556+
} else {
557+
[String: String]()
558+
}
552559
let router = ObjectsUserRouter(
553-
.set(
554-
metadata: metadata,
555-
include: include.includeFields
556-
),
557-
configuration: requestConfig.customConfiguration ?? configuration
560+
.set(metadata: metadata, include: include.includeFields),
561+
configuration: requestConfig.customConfiguration ?? configuration,
562+
customHeaders: customHeadersIfAny
558563
)
559564

560565
route(
@@ -760,20 +765,28 @@ public extension PubNub {
760765
///
761766
/// - Parameters:
762767
/// - metadata: The `PubNubChannelMetadata` to set
768+
/// - ifMatchesEtag: The entity tag to be used for the `If-Match` HTTP header to enable conditional requests
763769
/// - include: Include respective additional fields in the response.
764770
/// - custom: Custom configuration overrides for this request
765771
/// - completion: The async `Result` of the method call
766772
/// - **Success**: The `PubNubChannelMetadata` containing the set changes
767773
/// - **Failure**: An `Error` describing the failure
768774
func setChannelMetadata(
769775
_ metadata: PubNubChannelMetadata,
776+
ifMatchesEtag: String? = nil,
770777
include: ChannelIncludeFields = ChannelIncludeFields(),
771778
custom requestConfig: RequestConfiguration = RequestConfiguration(),
772779
completion: ((Result<PubNubChannelMetadata, Error>) -> Void)?
773780
) {
781+
let customHeadersIfAny = if let entityTag = ifMatchesEtag {
782+
[Constant.ifMatchHeaderKey: entityTag]
783+
} else {
784+
[String: String]()
785+
}
774786
let router = ObjectsChannelRouter(
775787
.set(metadata: metadata, include: include.includeFields),
776-
configuration: requestConfig.customConfiguration ?? configuration
788+
configuration: requestConfig.customConfiguration ?? configuration,
789+
customHeaders: customHeadersIfAny
777790
)
778791

779792
route(

Sources/PubNub/Helpers/Constants.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public enum Constant {
5757

5858
static let pubnubSwiftSDKName: String = "PubNubSwift"
5959

60-
static let pubnubSwiftSDKVersion: String = "8.2.5"
60+
static let pubnubSwiftSDKVersion: String = "8.3.0"
6161

6262
static let appBundleId: String = {
6363
if let info = Bundle.main.infoDictionary,
@@ -167,6 +167,12 @@ public extension Constant {
167167
/// [RFC6585 section 4](https://datatracker.ietf.org/doc/html/rfc6585#section-4)
168168
static let retryAfterHeaderKey = "Retry-After"
169169

170+
/// The HTTP `If-Match` request header makes a request conditional. A server will return resources for `GET` and `HEAD` methods, or upload resource for `PUT` and other non-safe methods, only if the resource
171+
/// matches one of the `ETag` values in the `If-Match` request header. If the conditional does not match, the `412 Precondition Failed` response is returned instead.
172+
///
173+
/// [RFC7232 section 3.1](https://datatracker.ietf.org/doc/html/rfc7232#section-3.1)
174+
static let ifMatchHeaderKey = "If-Match"
175+
170176
internal static let defaultUserAgentHeader: String = {
171177
let userAgent: String = {
172178
let appNameVersion = "\(Constant.appBundleId)/\(Constant.appVersion)"

Sources/PubNub/KMP/KMPPubNub+AppContext.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ public extension KMPPubNub {
164164
custom: KMPAnyJSON?,
165165
type: String?,
166166
status: String?,
167+
ifMatchesEtag: String?,
167168
include includeFields: KMPChannelIncludeFields,
168169
onSuccess: @escaping ((KMPChannelMetadata) -> Void),
169170
onFailure: @escaping ((Error) -> Void)
@@ -176,7 +177,11 @@ public extension KMPPubNub {
176177
channelDescription: description,
177178
custom: convertDictionaryToScalars(custom?.asMap())
178179
)
179-
pubnub.setChannelMetadata(channelMetadata, include: mapToChannelIncludeFields(from: includeFields)) {
180+
pubnub.setChannelMetadata(
181+
channelMetadata,
182+
ifMatchesEtag: ifMatchesEtag,
183+
include: mapToChannelIncludeFields(from: includeFields)
184+
) {
180185
switch $0 {
181186
case .success(let metadata):
182187
onSuccess(KMPChannelMetadata(metadata: metadata))
@@ -255,6 +260,7 @@ public extension KMPPubNub {
255260
custom: KMPAnyJSON?,
256261
type: String?,
257262
status: String?,
263+
ifMatchesEtag: String?,
258264
include includeFields: KMPUserIncludeFields,
259265
onSuccess: @escaping ((KMPUserMetadata) -> Void),
260266
onFailure: @escaping ((Error) -> Void)
@@ -269,7 +275,11 @@ public extension KMPPubNub {
269275
email: email,
270276
custom: convertDictionaryToScalars(custom?.asMap())
271277
)
272-
pubnub.setUserMetadata(userMetadata, include: mapToPubNubUserIncludeFields(from: includeFields)) {
278+
pubnub.setUserMetadata(
279+
userMetadata,
280+
ifMatchesEtag: ifMatchesEtag,
281+
include: mapToPubNubUserIncludeFields(from: includeFields)
282+
) {
273283
switch $0 {
274284
case .success(let metadata):
275285
onSuccess(KMPUserMetadata(metadata: metadata))

Sources/PubNub/Networking/Routers/ObjectsChannelRouter.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ public struct ObjectsChannelRouter: HTTPRouter {
5757
}
5858

5959
// Init
60-
public init(_ endpoint: Endpoint, configuration: RouterConfiguration) {
60+
public init(_ endpoint: Endpoint, configuration: RouterConfiguration, customHeaders: [String: String] = [:]) {
6161
self.endpoint = endpoint
6262
self.configuration = configuration
63+
self.customHeaders = customHeaders
6364
}
6465

6566
public var endpoint: Endpoint
6667
public var configuration: RouterConfiguration
68+
public var customHeaders: [String: String]
6769

6870
// Protocol Properties
6971
public var service: PubNubService {
@@ -74,6 +76,10 @@ public struct ObjectsChannelRouter: HTTPRouter {
7476
return endpoint.description
7577
}
7678

79+
public var additionalHeaders: [String: String] {
80+
customHeaders
81+
}
82+
7783
public var path: Result<String, Error> {
7884
let path: String
7985

Sources/PubNub/Networking/Routers/ObjectsUserRouter.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,15 @@ public struct ObjectsUserRouter: HTTPRouter {
6464
}
6565

6666
// Init
67-
public init(_ endpoint: Endpoint, configuration: RouterConfiguration) {
67+
public init(_ endpoint: Endpoint, configuration: RouterConfiguration, customHeaders: [String: String] = [:]) {
6868
self.endpoint = endpoint
6969
self.configuration = configuration
70+
self.customHeaders = customHeaders
7071
}
7172

7273
public var endpoint: Endpoint
7374
public var configuration: RouterConfiguration
75+
public var customHeaders: [String: String]
7476

7577
// Protocol Properties
7678
public var service: PubNubService {
@@ -81,6 +83,10 @@ public struct ObjectsUserRouter: HTTPRouter {
8183
return endpoint.description
8284
}
8385

86+
public var additionalHeaders: [String: String] {
87+
customHeaders
88+
}
89+
8490
public var path: Result<String, Error> {
8591
let path: String
8692

0 commit comments

Comments
 (0)