Skip to content

Commit 859bdca

Browse files
author
Arief Nur Putranto
committed
update param deviceId when registerDeviceToken
1 parent 69c2cf4 commit 859bdca

File tree

6 files changed

+122
-9
lines changed

6 files changed

+122
-9
lines changed

QiscusCore.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 = "QiscusCore"
3-
s.version = "1.13.3"
3+
s.version = "1.13.4"
44
s.summary = "Qiscus Core SDK for iOS"
55
s.description = <<-DESC
66
Qiscus SDK for iOS contains Qiscus public Model.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ let package = Package(
4646
)
4747
```
4848

49-
## Installation Carthage
49+
## Installation Carthage
5050
[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate QiscusCore into your Xcode project using Carthage, specify it in your Cartfile:
5151

5252
```bash

Source/QiscusCore/Network/NetworkManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ extension NetworkManager {
346346
/// - deviceToken: string device token for push notification
347347
/// - isDevelopment : default is false / using production
348348
/// - completion: @escaping when success register device token to sdk server returning value bool(success or not) and Optional String(error message)
349-
func registerDeviceToken(deviceToken: String, isDevelopment: Bool = false, bundleId : String = "", onSuccess: @escaping (Bool) -> Void, onError: @escaping (QError) -> Void) {
350-
clientRouter.request(.registerDeviceToken(token: deviceToken, isDevelopment: isDevelopment, bundleId: bundleId)) { (data, response, error) in
349+
func registerDeviceToken(deviceToken: String, isDevelopment: Bool = false, bundleId : String = "", deviceId : String = "", onSuccess: @escaping (Bool) -> Void, onError: @escaping (QError) -> Void) {
350+
clientRouter.request(.registerDeviceToken(token: deviceToken, isDevelopment: isDevelopment, bundleId: bundleId, deviceId : deviceId)) { (data, response, error) in
351351
if error != nil {
352352
onError(QError(message: error?.localizedDescription ?? "Please check your network connection."))
353353
}

Source/QiscusCore/Network/Service/Endpoint.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ internal enum APIClient {
7979
case sync(lastReceivedCommentId: String)
8080
case syncEvent(startEventId : String)
8181
case search(keyword: String, roomId: String?, lastCommentId: Int?)
82-
case registerDeviceToken(token: String, isDevelopment: Bool, bundleId: String) //
82+
case registerDeviceToken(token: String, isDevelopment: Bool, bundleId: String, deviceId: String) //
8383
case removeDeviceToken(token: String, isDevelopment: Bool) //
8484
case loginRegister(user: String, password: String , username: String?, avatarUrl: String?, extras: [String:Any]?) //
8585
case loginRegisterJWT(identityToken: String) //
@@ -107,7 +107,7 @@ extension APIClient : EndPoint {
107107
return "/sync_event"
108108
case .search( _, _, _):
109109
return "/search_messages"
110-
case .registerDeviceToken( _, _, _):
110+
case .registerDeviceToken( _, _, _, _):
111111
return "/set_user_device_token"
112112
case .removeDeviceToken( _, _):
113113
return "/remove_user_device_token"
@@ -177,12 +177,13 @@ extension APIClient : EndPoint {
177177
}
178178

179179
return .requestParameters(bodyParameters: param, bodyEncoding: .jsonEncoding, urlParameters: nil)
180-
case .registerDeviceToken(let token, let isDevelopment, let bundleId):
180+
case .registerDeviceToken(let token, let isDevelopment, let bundleId, let deviceId):
181181
let param = [
182182
"device_token" : token,
183183
"device_platform" : "ios",
184184
"is_development" : isDevelopment,
185-
"bundle_id" : bundleId
185+
"bundle_id" : bundleId,
186+
"device_id" : deviceId
186187
] as [String : Any]
187188
return .requestParameters(bodyParameters: param, bodyEncoding: .jsonEncoding, urlParameters: nil)
188189
case .removeDeviceToken(let token, let isDevelopment):

Source/QiscusCore/QiscusCore.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,15 @@ public class QiscusCore: NSObject {
714714
/// - completion: The code to be executed once the request has finished
715715
public func registerDeviceToken(token : String, isDevelopment:Bool = false, bundleId : String = "", onSuccess: @escaping (Bool) -> Void, onError: @escaping (QError) -> Void) {
716716
if QiscusCore.isLogined {
717-
QiscusCore.network.registerDeviceToken(deviceToken: token, isDevelopment: isDevelopment, bundleId: bundleId, onSuccess: { (success) in
717+
var bundleID = ""
718+
if bundleId.isEmpty {
719+
bundleID = Bundle.main.bundleIdentifier ?? ""
720+
}else{
721+
bundleID = bundleId
722+
}
723+
724+
let deviceId = getUUID(bundleId: bundleID) ?? ""
725+
QiscusCore.network.registerDeviceToken(deviceToken: token, isDevelopment: isDevelopment, bundleId: bundleID, deviceId: deviceId, onSuccess: { (success) in
718726
onSuccess(success)
719727
}) { (error) in
720728
onError(error)
@@ -724,6 +732,32 @@ public class QiscusCore: NSObject {
724732
}
725733
}
726734

735+
/// Creates a new unique user identifier or retrieves the last one created
736+
private func getUUID(bundleId : String) -> String? {
737+
738+
// create a keychain helper instance
739+
let keychain = QKeychainAccess()
740+
741+
// this is the key we'll use to store the uuid in the keychain
742+
let uuidKey = "\(bundleId).unique_uuid"
743+
744+
// check if we already have a uuid stored, if so return it
745+
if let uuid = try? keychain.queryKeychainData(itemKey: uuidKey), uuid != nil {
746+
return uuid
747+
}
748+
749+
// generate a new id
750+
guard let newId = UIDevice.current.identifierForVendor?.uuidString else {
751+
return nil
752+
}
753+
754+
// store new identifier in keychain
755+
try? keychain.addKeychainData(itemKey: uuidKey, itemValue: newId)
756+
757+
// return new id
758+
return newId
759+
}
760+
727761
/// Remove device token
728762
///
729763
/// - Parameters:
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//
2+
// QKeychainAccess.swift
3+
// QiscusCore
4+
//
5+
// Created by arief nur putranto on 05/11/24.
6+
//
7+
8+
import Foundation
9+
10+
class QKeychainAccess {
11+
12+
func addKeychainData(itemKey: String, itemValue: String) throws {
13+
guard let valueData = itemValue.data(using: .utf8) else {
14+
print("Keychain: Unable to store data, invalid input - key: \(itemKey), value: \(itemValue)")
15+
return
16+
}
17+
18+
//delete old value if stored first
19+
do {
20+
try deleteKeychainData(itemKey: itemKey)
21+
} catch {
22+
print("Keychain: nothing to delete...")
23+
}
24+
25+
let queryAdd: [String: AnyObject] = [
26+
kSecClass as String: kSecClassGenericPassword,
27+
kSecAttrAccount as String: itemKey as AnyObject,
28+
kSecValueData as String: valueData as AnyObject,
29+
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
30+
]
31+
let resultCode: OSStatus = SecItemAdd(queryAdd as CFDictionary, nil)
32+
33+
if resultCode != 0 {
34+
print("Keychain: value not added - Error: \(resultCode)")
35+
} else {
36+
print("Keychain: value added successfully")
37+
}
38+
}
39+
40+
func deleteKeychainData(itemKey: String) throws {
41+
let queryDelete: [String: AnyObject] = [
42+
kSecClass as String: kSecClassGenericPassword,
43+
kSecAttrAccount as String: itemKey as AnyObject
44+
]
45+
46+
let resultCodeDelete = SecItemDelete(queryDelete as CFDictionary)
47+
48+
if resultCodeDelete != 0 {
49+
print("Keychain: unable to delete from keychain: \(resultCodeDelete)")
50+
} else {
51+
print("Keychain: successfully deleted item")
52+
}
53+
}
54+
55+
func queryKeychainData (itemKey: String) throws -> String? {
56+
let queryLoad: [String: AnyObject] = [
57+
kSecClass as String: kSecClassGenericPassword,
58+
kSecAttrAccount as String: itemKey as AnyObject,
59+
kSecReturnData as String: kCFBooleanTrue,
60+
kSecMatchLimit as String: kSecMatchLimitOne
61+
]
62+
var result: AnyObject?
63+
let resultCodeLoad = withUnsafeMutablePointer(to: &result) {
64+
SecItemCopyMatching(queryLoad as CFDictionary, UnsafeMutablePointer($0))
65+
}
66+
67+
if resultCodeLoad != 0 {
68+
print("Keychain: unable to load data - \(resultCodeLoad)")
69+
return nil
70+
}
71+
72+
guard let resultVal = result as? NSData, let keyValue = NSString(data: resultVal as Data, encoding: String.Encoding.utf8.rawValue) as String? else {
73+
print("Keychain: error parsing keychain result - \(resultCodeLoad)")
74+
return nil
75+
}
76+
return keyValue
77+
}
78+
}

0 commit comments

Comments
 (0)