封装社交SDK遇到的坑及设计思路

引言

戏精项目中涉及到使用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

        /*..回调的具体操作..*/

}

提升方向

封装第三方内容更丰富

减少大小

增强通用型

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容