SDK开发中我们可能希望使用已有的第三方开源库,比如在发送请求的功能上我们更希望用AFNetworking而非直接使用NSURLSession,又如在实现socket连接时我们更希望用SocketRocket而非自己从零实现。但如果我们直接把AFNetworking的源文件拖到静态库SDK里,而宿主APP也引入了AFNetworking,这时运行代码就会报符号冲突(duplicate symbols)的错误。
这时大部分人的解决方案都是手动修改引入到SDK里的开源库代码,包括类名、分类名、全局常量名、协议名等会导致冲突的符号。其实对于像AFNetworking(v3.2.1)这种源码量较少的第三方库来说,需要修改的地方都要多达47个,可想而知这是一项多么低效和易错的解决方案,而且如果下次需要升级SDK中的该第三方库,你需要再重新手动改一遍……下边我们来一步步深入解决这件麻烦事。
首先我们考虑下怎样避免每次都要修改第三方库源码,如果有一个单独的文件来存原符号和重命名符号的对应关系就好了,我们自然而然地会想到用宏定义。创建一个头文件,比如叫XNGNamespace.h
// XNGNamespace.h
#define AFURLSessionManager XNGURLSessionManager
#define AFNetworkingReachabilityDidChangeNotification XNGNetworkingReachabilityDidChangeNotification
#define AFImageResponseSerializer XNGImageResponseSerializer
...
然后在你的SDK工程中,如果你已经有一个预编译头文件(一般为xxx.pch),在最上一行引入XNGNamespace.h,否则在Build Settings -> Prefix Header配置该文件的路径(即把这个文件作为预编译头文件)。这时你可以在Xcode中看到原本的比如AFURLSessionManager
类名颜色变成和宏一样的颜色,准确地说,这个类现在其实叫XNGURLSessionManager
了。
现在有了这个文件后,即使要升级SDK中的第三方库,我们也只需要在这个文件里做少量增删了。
但到目前为止最麻烦的这部分事还没解决,毕竟现在还是要靠肉眼找出那些符号