微博 SDK 的接入不难,本 Handler 基于微博 SDK 3.2.7 实现。
General
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class WeiboSDKHandler {
public let endpoints: [Endpoint] = [ Endpoints.Weibo.timeline, ]
public let platform: Platform = Platforms.weibo
public var isInstalled: Bool { WeiboSDK.isWeiboAppInstalled() }
private var shareCompletionHandler: Bus.ShareCompletionHandler? private var oauthCompletionHandler: Bus.OauthCompletionHandler?
public let appID: String private let redirectLink: URL
public var logHandler: Bus.LogHandler = { message, _, _, _ in #if DEBUG print(message) #endif }
private var helper: Helper!
public init(appID: String, redirectLink: URL) { self.appID = appID self.redirectLink = redirectLink
helper = Helper(master: self)
#if DEBUG WeiboSDK.enableDebugMode(true) #endif
WeiboSDK.registerApp( appID.trimmingCharacters(in: .letters) ) } }
|
调用 WeiboSDK.registerApp(_:)
注册微博 SDK,调用 WeiboSDK.enableDebugMode(_:)
记录日志。Helper
处理微博的回调,相关内容下文会进行说明。
LogHandlerProxyType
1
| extension WeiboSDKHandler: LogHandlerProxyType {}
|
声明 WeiboSDKHandler
遵循 LogHandlerProxyType
协议。
ShareHandlerType
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| extension WeiboSDKHandler: ShareHandlerType {
public func share( message: MessageType, to endpoint: Endpoint, options: [Bus.ShareOptionKey: Any] = [:], completionHandler: @escaping Bus.ShareCompletionHandler ) { guard isInstalled else { completionHandler(.failure(.missingApplication)) return }
shareCompletionHandler = completionHandler
let request = WBSendMessageToWeiboRequest() request.message = WBMessageObject()
switch message { case let message as TextMessage: request.message.text = message.text
case let message as ImageMessage: let imageObject = WBImageObject() imageObject.imageData = message.data
request.message.imageObject = imageObject
case let message as WebPageMessage: let webPageObject = WBWebpageObject() webPageObject.webpageUrl = message.link.absoluteString webPageObject.title = message.title webPageObject.description = message.description webPageObject.thumbnailData = message.thumbnail
webPageObject.objectID = UUID().uuidString
request.message.mediaObject = webPageObject
default: completionHandler(.failure(.unsupportedMessage)) return }
let result = WeiboSDK.send(request)
if !result { completionHandler(.failure(.invalidMessage)) } } }
|
在分享流程中:
- 调用
isInstalled
判断是否安装微博,没有则提前退出。
- 创建
WBSendMessageToWeiboRequest
请求。
- 创建
WBMessageObject
多媒体消息。
- 判断
message
的具体类型,设置 request.message
的相关属性。注意 WBWebpageObject
需要设置 objectID
。
- 调用
WeiboSDK.send(_:)
拉起微博分享。
OauthHandlerType
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| extension WeiboSDKHandler: OauthHandlerType {
public func oauth( options: [Bus.OauthOptionKey: Any] = [:], completionHandler: @escaping Bus.OauthCompletionHandler ) { guard isInstalled else { completionHandler(.failure(.missingApplication)) return }
oauthCompletionHandler = completionHandler
let request = WBAuthorizeRequest() request.redirectURI = redirectLink.absoluteString
let result = WeiboSDK.send(request)
if !result { completionHandler(.failure(.unknown)) } } }
|
在登录流程中:
- 调用
isInstalled
判断是否安装微博,没有则提前退出。
- 创建
WBAuthorizeRequest
请求。
- 调用
WeiboSDK.send(_:)
拉起微博登录。
OpenURLHandlerType
1 2 3 4 5 6
| extension WeiboSDKHandler: OpenURLHandlerType {
public func openURL(_ url: URL) { WeiboSDK.handleOpen(url, delegate: helper) } }
|
调用 WeiboSDK.handleOpen(_:delegate:)
处理 URL Scheme
回调。
Helper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| extension WeiboSDKHandler {
fileprivate class Helper: NSObject, WeiboSDKDelegate {
weak var master: WeiboSDKHandler?
required init(master: WeiboSDKHandler) { self.master = master }
func didReceiveWeiboRequest(_ request: WBBaseRequest!) { assertionFailure("\(String(describing: request))") }
func didReceiveWeiboResponse(_ response: WBBaseResponse!) { switch response { case let response as WBSendMessageToWeiboResponse: switch response.statusCode { case .success: master?.shareCompletionHandler?(.success(())) case .userCancel: master?.shareCompletionHandler?(.failure(.userCancelled)) default: master?.shareCompletionHandler?(.failure(.unknown)) } case let response as WBAuthorizeResponse: switch (response.statusCode, response.accessToken) { case let (.success, accessToken): let parameters = [ OauthInfoKeys.accessToken: accessToken, ] .compactMapContent()
if !parameters.isEmpty { master?.oauthCompletionHandler?(.success(parameters)) } else { master?.oauthCompletionHandler?(.failure(.unknown)) } case (.userCancel, _): master?.oauthCompletionHandler?(.failure(.userCancelled)) default: master?.oauthCompletionHandler?(.failure(.unknown)) } default: assertionFailure("\(String(describing: response))") } } } }
extension WeiboSDKHandler {
public enum OauthInfoKeys {
public static let accessToken = Bus.OauthInfoKey(rawValue: "com.nuomi1.bus.weiboSDKHandler.accessToken") } }
|
创建 Helper
处理微博的回调:
WeiboSDKHandler
强持有 Helper
,所以 Helper
的 master
声明为 weak
避免循环引用。
- 处理分享回调时,返回
WBSendMessageToWeiboResponse
,调用 response.statusCode
判断是否为 .success
,调用 master?.shareCompletionHandler?(.success(()))
完成分享回调。
- 处理登录回调时,返回
WBAuthorizeResponse
,调用 response.statusCode
和 response.accessToken
判断成功且 accessToken
不为空时,调用 master?.oauthCompletionHandler?(.success(parameters))
完成登录回调。
总结
本文通过封装微博 SDK 做出 WeiboSDKHandler
,实现微博的登录和分享功能。微博支持的多媒体消息与微博或 QQ 不太一样,因此只实现了以上几个。同时微博 SDK 只能打包到主工程,需要特别注意。
参考
- Weibo - ReadMe