专栏名称: 知识小集
目录
相关文章推荐
发现新西兰  ·  突发:新西兰国会“封杀”DeepSeek!微 ... ·  4 天前  
发现新西兰  ·  新西兰脑癌患者用DeepSeek给自己看病, ... ·  5 天前  
51好读  ›  专栏  ›  知识小集

「 iOS知识小集 」2018 · 第 41 期

知识小集  · 掘金  ·  · 2018-12-17 05:07

正文

阅读 133

「 iOS知识小集 」2018 · 第 41 期

原文链接

上周公众号发布的以下文章:

本期知识小集的主要内容包括:

  • 一入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 代码中完成。







请到「今天看啥」查看全文