引言
戏精项目中涉及到使用QQ、微信、微博进行登陆、获取用户信息、分享等操作,考虑到各个应用程序在接入这些SDK时需要操作的事项十分雷同,为减少客户端开发人员的学习成本和开发成本,将QQSDK、微信SDK、微博SDK(如有需求也会接入Facebook)的注册、登陆、获取用户信息、分享等功能进行封装形成XJSocialSDK。
本篇文章不会详细的介绍如何基于Swift的Framework而会把重点放在接入SDK过程中产生的一些坑和XJSocialSDK的设计整体思路设计及以及在项目中如何运用XJSocialSDK。
对于不了解如何制作基于Swift的Framework需要可以参考制作基于Swift 的Framework(通过module桥接引用oc.framework)该篇文章的介绍已经十分详细。
踩坑篇
按照上面文章的介绍将社交SDK们加入到XJSharingSDK到确保其能够正常使用,主要涉及以下两个方面的问题。
缺少依赖库
每个社交framework都需要引入相关系统依赖SDK,按照各个SDK文档可以找到相关的依赖库,加入项目中。
wechat:
SystemConfiguration.framework
libz.dylib
libsqlite3.0.dylib
qq:
SystemConfiguration.framework
weibo:
QuartzCore.framework
ImageIO.framework
SystemConfiguration.framework
Security.framework
CoreTelephony.framework
CoreText.framework
CoreGraphics.framework
libz.dylib
libsqlite3.dylib
然而直接运行,无发正常编译:
"_OBJC_CLASS_$_PHAsset", referenced from: objc-class-ref in libWeiboSDK.a(WBImageObject.o) objc-class-ref in libWeiboSDK.a(WBNewVideoObject.o)
"_OBJC_CLASS_$_PHAssetChangeRequest", referenced from: objc-class-ref in libWeiboSDK.a(WBImageObject.o) objc-class-ref in libWeiboSDK.a(WBNewVideoObject.o)
"_OBJC_CLASS_$_PHPhotoLibrary", referenced from: objc-class-ref in libWeiboSDK.a(WBImageObject.o) objc-class-ref in libWeiboSDK.a(WBNewVideoObject.o)
确保微博SDK的正常运行还需要引入依赖库Photos.framework
微博使用register方法导致程序崩溃
测试XJSocialSDK可用性阶段,发现只要工程中调用了
WeiboSDK.registerApp(appID)
会发现运行到weiboSDK的WBAidManager出现错误。
#2 0x00000001029b0a74 in -[WBMFPRSA getPublicKey] at /Users/insomnia/Desktop/git_Weibo_sdk/WeiboSDKSrc/WeiboSDK/WBAidManager.m:531
是因为weiboSDK在register阶段需要从Main Bundle中调用WeiboSDK.bundle,因为被直接封装在XJSocialSDK中,XJSocialSDK的WeiboSDK.bundle不会被加入到Main Bundle中,所以需要在项目中使用需要手动将WeiboSDK.bundle文件添加到项目中,才能保证register阶段的正常运行。
设计篇
XJSocialSDK的设计从业务实现的层面去考虑,将其划分为以下四个大模块:
注册、登陆模块
数据持久化模块
分享模块
信息处理模块
微信、微博、QQ对应的闭包说明
// 微信handler
// 完成状态、内容说明
public typealias WechatResponseComplete = ((ResponseCompleteState, String) -> Void)
// 微博handler
// 完成状态、userId和token、UserInfo
public typealias WeiboResponseComplete = ((ResponseCompleteState, WeiboAuth?, [AnyHashable : Any]?) -> Void)
// QQhandler
// 完成状态、用户信息
public typealias QQResponseComplete = ((ResponseCompleteState, [String: Any]?) -> Void)
通过这四个模块的组合,将XJSharingSDK处理的事务分成以下三个部分:
注册
registerdata
在这个阶段除了代替用户向微信、微博、QQ注册App之外,SDK负责将注册信息存在实现NSCoding协议的AuthInfo类中,使其能够通过序列化和反序列化存在UserDefault中。
使用案例
XJRegisterHandler().weiboRegister("1462566154", oredirectUri: "https://api.weibo.com/oauth2/default.html")
登陆
dataloginhandle
根据注册的信息,向第三方平台发送登陆请求,根据代理回调的场景将Handle返回业务层。
使用案例
XJRegisterHandler().wechatLogin("snsapi_userinfo", state: "default_state") { (state, info) in /*state表示登陆成功与否的状态*/ }
分享
datasharehandle
在不同平台下分享不同的内容类型都有相似的逻辑:
验证AppKey相关
分享的信息体
通过分享类型调用对应的API
各平台SDK关于分享部分的封装比较类似,下面介绍封装微博分享部分的实现来说明XJSocialSDK的分享模块的设计。
传入Model构造
针对每一个分享类型设置一个结构体,所有的信息结构体都遵从某一个协议,这种方式对于使用者而言只需要有一个接口就可以实现各种类型的分享。
weibo相关的结构体如下所示:
public protocol WeiboSharingProtocol {
var userInfo: [String: Any]? {get}
}
public struct WeiboSharingText: WeiboSharingProtocol {
public var userInfo: [String : Any]?
public var text: String?
public init(_ userInfo: [String: Any]? = nil, text: String) {
self.userInfo = userInfo self.text = text
}
}
public struct WeiboSharingImage: WeiboSharingProtocol {
public var userInfo: [String : Any]?
public var imgData: Data
public var text: String? = nil
public init(_ userInfo: [String: Any]? = nil, imgData: Data, text: String? = nil) {
self.userInfo = userInfo
self.imgData = imgData
self.text = text
}
}
public struct WeiboSharingUrl: WeiboSharingProtocol {
public var userInfo: [String : Any]?
public var url: String
public var title: String
public var text: String? = nil
public var thumbImgData: Data? = nil
public var description: String? = nil
public init(_ userInfo: [String: Any]? = nil, url: String, title: String, text: String? = nil, thumbImgData: Data? = nil, description: String? = nil) {
self.userInfo = userInfo
self.url = url
self.title = title
self.text = text
self.thumbImgData = thumbImgData
self.description = description
}
}
通过switch的方式根据类型的不同去调用不同的分享方法即可。
func weiboSharing(_ shareType: ShareType, weiboSharingProtocol: WeiboSharingProtocol) {
switch shareType {
case .url:
WeiboSharing.singleton.shareUrl(weiboSharingProtocol)
case .text:
WeiboSharing.singleton.shareText(weiboSharingProtocol)
case .image:
WeiboSharing.singleton.shareImage(weiboSharingProtocol) default: break
}
}
使用案例
XJSharingHandler().weiboSharing(.text, weiboSharingProtocol: WeiboSharingText(nil, text: "测试微博分享")) { (state, auth, userInfo) in /*..回调的具体操作..*/ }
注:微信分享、QQ分享也按照微博的形式进行设计实现
使用篇
链接SDK。在项目中使用如果需要使用XJSocialSDK,只需要将打包生成的XJSocialSDK,QQSDK、WXSDK、WBSDK连接到项目中即可,别忘了因为微博官方SDK的缘故需要手动加入WeiboSDK.bundle到主工程中。
import XJSocialSDK。在需要使用项目文件中import SDK。
注册。在didFinishLaunchingWithOptions阶段register相关内容。
_ = XJRegisterHandler().wechatRegister("*******")
_ = XJRegisterHandler().weiboRegister("******", oredirectUri: "*****")
_ = XJRegisterHandler().qqRegister("*****")
登陆。在需要登陆的时候,调用登陆接口。
XJRegisterHandler().wechatLogin("snsapi_userinfo", state: "default_state") { (state, info) in /*state 表示登陆成功与否的状态*/ }
分享。在需要对内容进行分享的阶段,根据需求进行分享。
XJSharingHandler().wechatSharing(.text, wechatSharingProtocol: WechatSharingText(.Timeline, test: "sunyicheng")) { (state, info) in
/*.操作..*/
}
XJSharingHandler().weiboSharing(.text, weiboSharingProtocol: WeiboSharingText(nil, text: "测试微博分享")) { (state, auth, userInfo) in
/*..回调的具体操作..*/
}
提升方向
封装第三方内容更丰富
减少大小
增强通用型