上週公眾號釋出的以下文章:
本期知識小集的主要內容包括:
- 一入IAP深似海第二彈
- Xcode 10 / iOS 12 獲取 WiFi 資訊
- Swift 4.x 中使用 +load 和 +initialize
- SecRandomCopyBytes 生成偽隨機數
一入IAP深似海第二彈
作者: 高老師很忙
之前和大家分享過一次關於IAP的坑,最近又發現了一個新坑?:通常我們是根據-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)transactions
方法回撥來確認使用者支付成功還是失敗,從而進入不同的業務處理;然而我最近發現蘋果可能會返回錯誤的回撥,使用者實際已經支付成功,但是會先收到一次取消支付的回撥,然後馬上又收到一個支付成功的回撥。
針對這種情況,就需要我們在業務上進一步處理,同時還要兼顧之前分享的關於丟單處理的邏輯,防止丟單會涉及一些訂單資訊的本地儲存,之前可能會在收到取消支付回撥時刪除對應的本地訂單資訊,這種情況就需要重新補充訂單資訊。
Xcode 10 / iOS 12 獲取 WiFi 資訊
作者: KANGZUBIN
在一些特定業務場景下,我們需要獲取 iOS 裝置所連線的 WiFi 的資訊,比如 WiFi 的 SSID
(即 WiFi 的名稱),WiFi 的 BSSID
(即 WiFi 的路由器的 Mac 地址)等,相應的程式碼也很簡單,大致如下圖所示:
在 Xcode 10(iOS 12)之前,上述程式碼可以正常執行取到結果,但當升級到 Xcode 10 後編譯工程在 iOS 12 上執行時,同樣的程式碼卻無法取得 WiFi 的資訊。通過斷點除錯發現 CNCopyCurrentNetworkInfo(...)
函式總是返回 nil
,查閱官方 API 文件,發現該函式的描述多了一條重要提示,如下圖紅框內容:
大致意思是說:在 iOS 12 及以上系統呼叫該方法時,需要先在 Xcode 工程中授權獲取 WiFi 資訊的能力,開啟路徑為:Xcode -> [Project Name] -> Targets -> [Target Name] -> Capabilities -> Access WiFi Information -> ON,如下圖:
設定完畢後,我們可以發現在工程的 .entitlements
檔案會多了一對鍵值:
Access WiFi Information
=> YES
至此,我們就可以正常在 iOS 12+ 中獲取 WiFi 的資訊了。
Swift 4.x 中使用 +load 和 +initialize
+load 和 +initialize 方法是我們寫 Objective-C 程式碼時常用的兩個方法,不過貌似在 Swift 4.x 後,這兩個方法在 Swift 類中不那麼好使,會報如下編譯錯誤:
Method 'load()' defines Objective-C class method 'load', which is not permitted by Swift
Method 'initialize()' defines Objective-C class method 'initialize', which is not permitted by Swift
複製程式碼
所以,如果想在 Swift 類中使用這兩個方法,則需要求助於 Objective-C,使用變通的方法,如下程式碼所示:
// swift
class Monitor: NSObject {
@objc class func swiftLoad() {
// do something
print("swift load")
}
@objc class func swiftInitialize() {
// do something
print("swift initialize")
}
}
// Objective-C
@implementation Monitor (Private)
+ (void)load {
[self swiftLoad];
}
+ (void)initialize {
[self swiftInitialize];
}
@end
複製程式碼
當然,由於這兩個方法是 NSObject 類中宣告的,所以我們的 Swift 類必須繼承自 NSObject 或其子類。另外,我們也可以不用上面這麼麻煩地去定義 swiftLoad/swiftInitialize 方法,而是所有操作直接在 Objective-C 程式碼中完成。
SecRandomCopyBytes 生成偽隨機數
在iOS中,生成偽隨機數可以使用這麼幾個函式:rand()
、random()
、arc4random()
。另外我們知道隨機數是密碼技術的核心部分,所以 Apple 也為我們提供了相應的生成隨機數的方法,即 SecRandomCopyBytes,這個方法位於 Security.framework
中,所以使用時需要先匯入這個庫,使用的方法如下:
+ (NSString *)generateRandom {
static int size = 8;
uint8_t randomBytes[size];
int result = SecRandomCopyBytes(kSecRandomDefault, size, randomBytes);
if (result == errSecSuccess) {
NSMutableString *randomString = [[NSMutableString alloc] initWithCapacity:size * 2];
for (int i = 0; i < size; i++) {
[randomString appendFormat:@"%02x", randomBytes[i]];
}
return randomString;
} else {
return nil;
}
}
複製程式碼
這裡我們生成一個 8 位元組長的uint8_t陣列,然後將其轉換成 hex 字串得到一個長度16的隨機字條串。另外這個函式也可以作為生成 UUID 的輔助操作,如下程式碼所示:
+ (NSString*)generateCryptoSecureUUID
{
unsigned char bytes[16];
int result = SecRandomCopyBytes(kSecRandomDefault, 16, bytes);
if (result != noErr) {
return nil;
}
return [[NSUUID alloc] initWithUUIDBytes:bytes].UUIDString;
}
複製程式碼
關注我們
歡迎關注我們的公眾號:iOS-Tips,也歡迎加入我們的群組討論問題。可以公眾號留言 ios
、flutter
等關鍵詞獲取入群方式。