Skip to content

Commit

Permalink
update param deviceId when registerDeviceToken
Browse files Browse the repository at this point in the history
  • Loading branch information
Arief Nur Putranto committed Nov 6, 2024
1 parent 69c2cf4 commit 859bdca
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 9 deletions.
2 changes: 1 addition & 1 deletion QiscusCore.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "QiscusCore"
s.version = "1.13.3"
s.version = "1.13.4"
s.summary = "Qiscus Core SDK for iOS"
s.description = <<-DESC
Qiscus SDK for iOS contains Qiscus public Model.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ let package = Package(
)
```

## Installation Carthage
## Installation Carthage
[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:

```bash
Expand Down
4 changes: 2 additions & 2 deletions Source/QiscusCore/Network/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ extension NetworkManager {
/// - deviceToken: string device token for push notification
/// - isDevelopment : default is false / using production
/// - completion: @escaping when success register device token to sdk server returning value bool(success or not) and Optional String(error message)
func registerDeviceToken(deviceToken: String, isDevelopment: Bool = false, bundleId : String = "", onSuccess: @escaping (Bool) -> Void, onError: @escaping (QError) -> Void) {
clientRouter.request(.registerDeviceToken(token: deviceToken, isDevelopment: isDevelopment, bundleId: bundleId)) { (data, response, error) in
func registerDeviceToken(deviceToken: String, isDevelopment: Bool = false, bundleId : String = "", deviceId : String = "", onSuccess: @escaping (Bool) -> Void, onError: @escaping (QError) -> Void) {
clientRouter.request(.registerDeviceToken(token: deviceToken, isDevelopment: isDevelopment, bundleId: bundleId, deviceId : deviceId)) { (data, response, error) in
if error != nil {
onError(QError(message: error?.localizedDescription ?? "Please check your network connection."))
}
Expand Down
9 changes: 5 additions & 4 deletions Source/QiscusCore/Network/Service/Endpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ internal enum APIClient {
case sync(lastReceivedCommentId: String)
case syncEvent(startEventId : String)
case search(keyword: String, roomId: String?, lastCommentId: Int?)
case registerDeviceToken(token: String, isDevelopment: Bool, bundleId: String) //
case registerDeviceToken(token: String, isDevelopment: Bool, bundleId: String, deviceId: String) //
case removeDeviceToken(token: String, isDevelopment: Bool) //
case loginRegister(user: String, password: String , username: String?, avatarUrl: String?, extras: [String:Any]?) //
case loginRegisterJWT(identityToken: String) //
Expand Down Expand Up @@ -107,7 +107,7 @@ extension APIClient : EndPoint {
return "/sync_event"
case .search( _, _, _):
return "/search_messages"
case .registerDeviceToken( _, _, _):
case .registerDeviceToken( _, _, _, _):
return "/set_user_device_token"
case .removeDeviceToken( _, _):
return "/remove_user_device_token"
Expand Down Expand Up @@ -177,12 +177,13 @@ extension APIClient : EndPoint {
}

return .requestParameters(bodyParameters: param, bodyEncoding: .jsonEncoding, urlParameters: nil)
case .registerDeviceToken(let token, let isDevelopment, let bundleId):
case .registerDeviceToken(let token, let isDevelopment, let bundleId, let deviceId):
let param = [
"device_token" : token,
"device_platform" : "ios",
"is_development" : isDevelopment,
"bundle_id" : bundleId
"bundle_id" : bundleId,
"device_id" : deviceId
] as [String : Any]
return .requestParameters(bodyParameters: param, bodyEncoding: .jsonEncoding, urlParameters: nil)
case .removeDeviceToken(let token, let isDevelopment):
Expand Down
36 changes: 35 additions & 1 deletion Source/QiscusCore/QiscusCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,15 @@ public class QiscusCore: NSObject {
/// - completion: The code to be executed once the request has finished
public func registerDeviceToken(token : String, isDevelopment:Bool = false, bundleId : String = "", onSuccess: @escaping (Bool) -> Void, onError: @escaping (QError) -> Void) {
if QiscusCore.isLogined {
QiscusCore.network.registerDeviceToken(deviceToken: token, isDevelopment: isDevelopment, bundleId: bundleId, onSuccess: { (success) in
var bundleID = ""
if bundleId.isEmpty {
bundleID = Bundle.main.bundleIdentifier ?? ""
}else{
bundleID = bundleId
}

let deviceId = getUUID(bundleId: bundleID) ?? ""
QiscusCore.network.registerDeviceToken(deviceToken: token, isDevelopment: isDevelopment, bundleId: bundleID, deviceId: deviceId, onSuccess: { (success) in
onSuccess(success)
}) { (error) in
onError(error)
Expand All @@ -724,6 +732,32 @@ public class QiscusCore: NSObject {
}
}

/// Creates a new unique user identifier or retrieves the last one created
private func getUUID(bundleId : String) -> String? {

// create a keychain helper instance
let keychain = QKeychainAccess()

// this is the key we'll use to store the uuid in the keychain
let uuidKey = "\(bundleId).unique_uuid"

// check if we already have a uuid stored, if so return it
if let uuid = try? keychain.queryKeychainData(itemKey: uuidKey), uuid != nil {
return uuid
}

// generate a new id
guard let newId = UIDevice.current.identifierForVendor?.uuidString else {
return nil
}

// store new identifier in keychain
try? keychain.addKeychainData(itemKey: uuidKey, itemValue: newId)

// return new id
return newId
}

/// Remove device token
///
/// - Parameters:
Expand Down
78 changes: 78 additions & 0 deletions Source/QiscusCore/Util/QKeychainAccess.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// QKeychainAccess.swift
// QiscusCore
//
// Created by arief nur putranto on 05/11/24.
//

import Foundation

class QKeychainAccess {

func addKeychainData(itemKey: String, itemValue: String) throws {
guard let valueData = itemValue.data(using: .utf8) else {
print("Keychain: Unable to store data, invalid input - key: \(itemKey), value: \(itemValue)")
return
}

//delete old value if stored first
do {
try deleteKeychainData(itemKey: itemKey)
} catch {
print("Keychain: nothing to delete...")
}

let queryAdd: [String: AnyObject] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: itemKey as AnyObject,
kSecValueData as String: valueData as AnyObject,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
]
let resultCode: OSStatus = SecItemAdd(queryAdd as CFDictionary, nil)

if resultCode != 0 {
print("Keychain: value not added - Error: \(resultCode)")
} else {
print("Keychain: value added successfully")
}
}

func deleteKeychainData(itemKey: String) throws {
let queryDelete: [String: AnyObject] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: itemKey as AnyObject
]

let resultCodeDelete = SecItemDelete(queryDelete as CFDictionary)

if resultCodeDelete != 0 {
print("Keychain: unable to delete from keychain: \(resultCodeDelete)")
} else {
print("Keychain: successfully deleted item")
}
}

func queryKeychainData (itemKey: String) throws -> String? {
let queryLoad: [String: AnyObject] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: itemKey as AnyObject,
kSecReturnData as String: kCFBooleanTrue,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let resultCodeLoad = withUnsafeMutablePointer(to: &result) {
SecItemCopyMatching(queryLoad as CFDictionary, UnsafeMutablePointer($0))
}

if resultCodeLoad != 0 {
print("Keychain: unable to load data - \(resultCodeLoad)")
return nil
}

guard let resultVal = result as? NSData, let keyValue = NSString(data: resultVal as Data, encoding: String.Encoding.utf8.rawValue) as String? else {
print("Keychain: error parsing keychain result - \(resultCodeLoad)")
return nil
}
return keyValue
}
}

0 comments on commit 859bdca

Please sign in to comment.