移植AWS SDK至WatchOS:替换Reachability依赖的SystemConfiguration导入
嘿,我之前在把第三方SDK适配到WatchOS的时候也碰到过这个SystemConfiguration框架找不到的问题,刚好也研究过AWS SDK的适配,给你梳理下具体的解决办法和通用思路:
1. 条件编译替换头文件导入
首先找到AWSKSReachability.h里的#import <SystemConfiguration/SystemConfiguration.h>,把它替换成条件编译的代码,区分iOS/macOS和WatchOS环境:
#if !TARGET_OS_WATCH #import <SystemConfiguration/SystemConfiguration.h> #else // WatchOS环境下导入替代API的头文件 #import <Network/Network.h> #import <WatchConnectivity/WatchConnectivity.h> #endif
这样在WatchOS编译时就不会去导入不存在的SystemConfiguration框架了。
2. 重写可达性检测逻辑
原来的AWSKSReachability是基于SystemConfiguration的SCNetworkReachability实现的,WatchOS不支持这个API,所以需要替换成WatchOS兼容的方案,推荐用苹果官方的NWPathMonitor(Network框架,WatchOS 5+ 支持),这也是AFNetworking适配WatchOS时采用的方案。
你可以在AWSKSReachability.m里用条件编译重写核心逻辑,示例如下:
#if TARGET_OS_WATCH #import <Network/Network.h> @interface AWSKSReachability () @property (nonatomic, strong) NWPathMonitor *pathMonitor; @property (nonatomic, copy) void (^networkReachabilityStatusBlock)(AWSNetworkReachabilityStatus status); @end @implementation AWSKSReachability + (instancetype)reachabilityWithHostName:(NSString *)hostName { AWSKSReachability *reachability = [[self alloc] init]; reachability.pathMonitor = [[NWPathMonitor alloc] initWithHostname:hostName]; __weak typeof(self) weakSelf = reachability; reachability.pathMonitor.pathUpdateHandler = ^(NWPath *path) { __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) return; AWSNetworkReachabilityStatus status = AWSNetworkReachabilityStatusNotReachable; if (path.status == NWPathStatusSatisfied) { if (path.isExpensive) { status = AWSNetworkReachabilityStatusReachableViaWWAN; } else { status = AWSNetworkReachabilityStatusReachableViaWiFi; } } if (strongSelf.networkReachabilityStatusBlock) { strongSelf.networkReachabilityStatusBlock(status); } }; return reachability; } - (void)startNotifier { [self.pathMonitor startQueue:dispatch_queue_create("com.amazonaws.reachability", DISPATCH_QUEUE_SERIAL)]; } - (void)stopNotifier { [self.pathMonitor cancel]; self.pathMonitor = nil; } // 其他需要适配的方法,比如获取当前网络状态等 @end #endif
这样就能在WatchOS环境下用NWPathMonitor替代原来的可达性检测逻辑,和iOS端的API行为保持一致。
1. 优先使用NWPathMonitor(推荐)
这是苹果推出的现代网络可达性API,完全替代了SystemConfiguration里的SCNetworkReachability,支持所有现代Apple平台(包括WatchOS),功能更全面:
- 能监测具体的网络类型(WiFi、蜂窝、以太网等)
- 支持监测指定主机或服务的可达性
- 提供实时的路径变化回调
- 使用步骤:
- 导入
<Network/Network.h>框架 - 创建
NWPathMonitor实例,可指定主机或网络路径 - 设置
pathUpdateHandler回调处理网络状态变化 - 启动监测(需要指定一个调度队列)
- 导入
2. 基于WatchConnectivity的间接判断(仅适用于依赖iPhone的Watch应用)
如果你的Watch应用必须依赖iPhone的网络连接,可以通过WCSession的isReachable属性判断Watch是否能和iPhone通信,间接推断网络状态:
#import <WatchConnectivity/WatchConnectivity.h> // 初始化WCSession if ([WCSession isSupported]) { WCSession *session = [WCSession defaultSession]; session.delegate = self; [session activateSession]; } // 判断是否可达 BOOL isReachable = [WCSession defaultSession].isReachable;
注意:这个方法只能判断Watch和iPhone的连接状态,不能直接判断iPhone本身的网络状态,适合完全依赖iPhone联网的Watch应用。
3. 用条件编译隔离多平台代码
在所有涉及SystemConfiguration的代码块外层,用平台宏进行包裹,保证不同平台编译对应代码:
#if !TARGET_OS_WATCH // iOS/macOS下使用SystemConfiguration的代码 #import <SystemConfiguration/SystemConfiguration.h> // ... 原有逻辑 #else // WatchOS下的替代实现 #import <Network/Network.h> // ... NWPathMonitor或WatchConnectivity的逻辑 #endif
这种方式能让同一个代码库兼容多个平台,也是AFNetworking等开源库常用的适配方案。
内容的提问来源于stack exchange,提问作者Victor 'Chris' Cabral

