Skip to content

Commit

Permalink
[Fix]Update deviceToken to empty once unregister void notifications (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ipavlidakis authored Nov 29, 2024
1 parent 90a596b commit d3dc7cc
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
# Upcoming

### 🐞 Fixed
- By observing the `CallKitPushNotificationAdapter.deviceToken` you will be notified with an empty `deviceToken` value, once the object unregister push notifications. [#608](https://github.com/GetStream/stream-video-swift/pull/608)
- When a call you receive a ringing while the app isn't running (and the screen is locked), websocket connection wasn't recovered. [#600](https://github.com/GetStream/stream-video-swift/pull/600)

# [1.14.1](https://github.com/GetStream/stream-video-swift/releases/tag/1.14.1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,17 @@ fileprivate func content() {

voIPTokenObservationCancellable = callKitPushNotificationAdapter.$deviceToken.sink { [streamVideo] updatedDeviceToken in
Task {
if let lastVoIPToken {
try await streamVideo.deleteDevice(id: updatedDeviceToken)
do {
if let lastVoIPToken, !lastVoIPToken.isEmpty {
try await streamVideo.deleteDevice(id: lastVoIPToken)
}
if !updatedDeviceToken.isEmpty {
try await streamVideo.setVoipDevice(id: updatedDeviceToken)
}
lastVoIPToken = updatedDeviceToken
} catch {
print(error)
}
try await streamVideo.setVoipDevice(id: updatedDeviceToken)
lastVoIPToken = updatedDeviceToken
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ open class CallKitPushNotificationAdapter: NSObject, PKPushRegistryDelegate, Obs
#else
registry.delegate = nil
registry.desiredPushTypes = []
deviceToken = ""
#endif
}

Expand Down
92 changes: 66 additions & 26 deletions StreamVideoTests/CallKit/CallKitPushNotificationAdapterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,50 @@ final class CallKitPushNotificationAdapterTests: XCTestCase {
XCTAssertTrue(subject.registry.desiredPushTypes?.isEmpty ?? false)
}

func test_unregister_deviceTokenWasConfiguredCorrectly() {
let expectedDecodedToken = "test-device-token"
subject.register()
subject.pushRegistry(
subject.registry,
didUpdate: .dummy(expectedDecodedToken),
for: .voIP
)

XCTAssertEqual(subject.deviceToken.decodedHex, expectedDecodedToken)
subject.unregister()

XCTAssertTrue(subject.deviceToken.isEmpty)
}

// MARK: - pushRegistry(_:didUpdate:for:)

func test_pushRegistryDidUpdatePushCredentials_deviceTokenWasConfiguredCorrectly() {
simulateDeviceTokenFetch("mockDeviceToken")
let expected = "mock-device-token"
subject.pushRegistry(
subject.registry,
didUpdate: .dummy(expected),
for: .voIP
)

XCTAssertEqual(subject.deviceToken, "6d6f636b446576696365546f6b656e")
XCTAssertEqual(subject.deviceToken.decodedHex, expected)
}

// MARK: - pushRegistry(_:didInvalidatePushTokenFor:)

func test_pushRegistryDidInvalidatePushCredentials_deviceTokenWasConfiguredCorrectly() {
simulateDeviceTokenFetch("mockDeviceToken")
let expected = "mock-device-token"
subject.pushRegistry(
subject.registry,
didUpdate: .dummy(expected),
for: .voIP
)

subject.pushRegistry(
subject.registry,
didInvalidatePushTokenFor: .voIP
)

XCTAssertEqual(subject.deviceToken, "")
XCTAssertTrue(subject.deviceToken.isEmpty)
}

// MARK: - pushRegistry(_:didReceiveIncomingPushWith:for:completion:)
Expand Down Expand Up @@ -97,20 +122,6 @@ final class CallKitPushNotificationAdapterTests: XCTestCase {

// MARK: - Private helpers

private func simulateDeviceTokenFetch(_ token: String) {
let registry = subject.registry
let deviceToken = token.data(using: .utf8)!
let stubPushCredentials = MockPKPushCredentials()
stubPushCredentials.stubType = .voIP
stubPushCredentials.stubToken = deviceToken

subject.pushRegistry(
registry,
didUpdate: stubPushCredentials,
for: .voIP
)
}

@MainActor
private func assertDidReceivePushNotification(
_ content: CallKitPushNotificationAdapter.Content? = nil,
Expand Down Expand Up @@ -173,20 +184,49 @@ final class CallKitPushNotificationAdapterTests: XCTestCase {

// MARK: - Mocks

private final class MockPKPushCredentials: PKPushCredentials {
private final class MockPKPushPayload: PKPushPayload {

var stubType: PKPushType = .voIP
var stubToken: Data!
var stubDictionaryPayload: [AnyHashable: Any] = [:]

override var type: PKPushType { stubType }
override var token: Data { stubToken }
override var dictionaryPayload: [AnyHashable: Any] { stubDictionaryPayload }
}

private final class MockPKPushPayload: PKPushPayload {
private extension PKPushCredentials {
private final class MockPKPushCredentials: PKPushCredentials {
private let inputToken: Data
override var token: Data { inputToken }
init(_ input: String) {
inputToken = Data(input.utf8)
super.init()
}
}

var stubType: PKPushType = .voIP
var stubDictionaryPayload: [AnyHashable: Any] = [:]
static func dummy(_ token: String) -> PKPushCredentials {
MockPKPushCredentials(token)
}
}

override var type: PKPushType { stubType }
override var dictionaryPayload: [AnyHashable: Any] { stubDictionaryPayload }
private extension String {
var decodedHex: String {
var data = Data()
var currentIndex = startIndex

// Ensure the string has an even number of characters
guard count % 2 == 0 else { return "self" }

while currentIndex < endIndex {
let nextIndex = index(currentIndex, offsetBy: 2)
let byteString = self[currentIndex..<nextIndex]
if let byte = UInt8(byteString, radix: 16) {
data.append(byte)
} else {
return self
}
currentIndex = nextIndex
}

return String(data: data, encoding: .utf8) ?? self
}
}

0 comments on commit d3dc7cc

Please sign in to comment.