Last active
January 16, 2019 03:55
-
-
Save klaus01/c4159cae21fc3f43918d0e9b1f99f88a to your computer and use it in GitHub Desktop.
不集成微信 SDK 实现登录权限和分享内容
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AppDelegate: UIResponder, UIApplicationDelegate { | |
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { | |
let vc = SLAppStartUpVideoVC() | |
WeChatServices.appID = "xxxxx" | |
WeChatServices.appSecret = "xxxxx" | |
// 还需要配置 Info.plst 的 CFBundleURLTypes 和 LSApplicationQueriesSchemes | |
// 分享链接给好友 | |
let content = WeChatServices.ShareContent.link(title: "标题", | |
description: "说明", | |
thumbnail: 缩略图 UIImage, | |
like: "链接") | |
WeChatServices.share(content: content, to: .friend, success: { (resultDic) in | |
log.info(resultDic) | |
}, fail: { (resultDic, error) in | |
log.error(resultDic) | |
log.error(error) | |
}) | |
// 授权登录 | |
WeChatServices.auth(success: { (dic) in | |
log.info(["登录成功", dic]) | |
}, fail: { (dic, error) in | |
log.error(["微信登录失败", error]) | |
}) | |
return true | |
} | |
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { | |
if WeChatServices.handleOpenURL(url) { return true } | |
return false | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// WeChatServices.swift | |
// SuperLine | |
// | |
// Created by 柯磊 on 2018/12/3. | |
// Copyright © 2018 AMonster. All rights reserved. | |
// | |
import UIKit | |
/// 微信业务 | |
struct WeChatServices { | |
/// 分享到 | |
/// | |
/// - friend: 好友 | |
/// - timeline: 朋友圈 | |
public enum ShareTo: Int { | |
case friend, timeline | |
} | |
/// 分享的内容 | |
/// | |
/// - link: 分享链接(标题,摘要,缩略图,链接) | |
public enum ShareContent { | |
case link(title: String, description: String?, thumbnail: UIImage?, like: String) | |
} | |
typealias WeChatServicesSuccess = ([String: Any]) -> Void | |
typealias WeChatServicesFail = ([String: Any]?, NSError) -> Void | |
static private let kErrorDomain = "WeChatServices" | |
static private let kAuthState = "MyWAuth" | |
static private var _successBlock: WeChatServicesSuccess? | |
static private var _failBlock: WeChatServicesFail? | |
/// 微信应用ID | |
static var appID: String! | |
/// 微信应用Secret | |
static var appSecret: String! | |
/// 是否安装了微信 | |
static var isInstalled: Bool { | |
if let url = URL(string: "weixin://"), UIApplication.shared.canOpenURL(url) { | |
return true | |
} | |
if let url = URL(string: "wechat://"), UIApplication.shared.canOpenURL(url) { | |
return true | |
} | |
return false | |
} | |
/// 调用授权 | |
/// | |
/// - Parameters: | |
/// - success: 成功回调 | |
/// - fail: 失败回调 | |
static func auth(success: WeChatServicesSuccess?, fail: WeChatServicesFail?) { | |
if !checkEnvironment() { return } | |
let urlString = String(format: "weixin://app/%@/auth/?scope=snsapi_userinfo&state=%@", appID!, kAuthState) | |
if let url = URL(string: urlString) { | |
_successBlock = success | |
_failBlock = fail | |
UIApplication.shared.openURL(url) | |
} else { | |
log.error("openURL 链接错误:" + urlString) | |
} | |
} | |
/// 分享内容 | |
/// | |
/// - Parameters: | |
/// - content: 分享内容及类型 | |
/// - to: 分享到哪儿 | |
static func share(content: ShareContent, to: ShareTo, success: WeChatServicesSuccess?, fail: WeChatServicesFail?) { | |
if !checkEnvironment() { return } | |
var shareDic = [String: Any]() | |
shareDic["result"] = "1" | |
shareDic["returnFromApp"] = "1" | |
shareDic["scene"] = to.rawValue.toString | |
shareDic["sdkver"] = "1.5" | |
shareDic["command"] = "1010" | |
switch content { | |
case .link(let title, let description, let thumbnail, let like): | |
shareDic["objectType"] = "5" | |
shareDic["title"] = title | |
shareDic["description"] = description ?? title | |
shareDic["mediaUrl"] = like | |
if let image = thumbnail { | |
shareDic["thumbData"] = image.jpegData(compressionQuality: 0.8) | |
} | |
} | |
do { | |
let data = try PropertyListSerialization.data(fromPropertyList: [appID: shareDic], format: .binary, options: 0) | |
UIPasteboard.general.setData(data, forPasteboardType: "content") | |
} catch let error as NSError { | |
log.error(error) | |
return | |
} | |
let urlString = String(format: "weixin://app/%@/sendreq/?", appID) | |
if let url = URL(string: urlString) { | |
_successBlock = success | |
_failBlock = fail | |
UIApplication.shared.openURL(url) | |
} else { | |
log.error("openURL 链接错误:" + urlString) | |
} | |
} | |
static func handleOpenURL(_ url: URL) -> Bool { | |
guard let scheme = url.scheme, scheme.hasPrefix("wx") else { | |
return false | |
} | |
if url.absoluteString.contains("://oauth"), let dic = url.queryParameters { | |
// 登录成功 | |
guard let code = dic["code"] else { | |
let error = NSError(domain: kErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "授权返回信息缺少 code"]) | |
_failBlock?(nil, error) | |
return true | |
} | |
log.info(["获取授权成功", dic]) | |
getAccessToken(code: code) | |
} else if let contentData = UIPasteboard.general.data(forPasteboardType: "content"), | |
let contentDic = try! PropertyListSerialization.propertyList(from: contentData, options: [], format: nil) as? [String: Any], | |
let appID = appID, | |
let resultDic = contentDic[appID] as? [String: Any], | |
let resultStr = resultDic["result"] as? String, | |
let result = resultStr.toInt() { | |
if let state = resultDic["state"] as? String, state == kAuthState, result != 0 { | |
// 登录失败 | |
let error = NSError(domain: kErrorDomain, code: result, userInfo: resultDic) | |
_failBlock?(resultDic, error) | |
return true | |
} else if result == 0 { | |
// 分享成功 | |
_successBlock?(resultDic) | |
} else { | |
// 分享失败 | |
let error = NSError(domain: kErrorDomain, code: result, userInfo: resultDic) | |
_failBlock?(resultDic, error) | |
} | |
} | |
return true | |
} | |
// MARK: - private methods | |
private static func checkEnvironment() -> Bool { | |
if appID == nil { | |
log.error("未设置微信 AppID") | |
return false | |
} | |
return true | |
} | |
private static func getAccessToken(code: String) { | |
let str = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code" | |
let urlString = String(format: str, appID!, appSecret!, code) | |
guard let url = URL(string: urlString) else { | |
let error = NSError(domain: kErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "生成获取授权信息链接失败"]) | |
_failBlock?(nil, error) | |
return | |
} | |
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, _, error) in | |
if let err = error { | |
DispatchQueue.main.async { | |
_failBlock?(nil, err as NSError) | |
} | |
return | |
} | |
guard let resultData = data else { | |
let error = NSError(domain: kErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "获取授权信息未返回数据"]) | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
return | |
} | |
do { | |
if let dic = try JSONSerialization.jsonObject(with: resultData, options: []) as? [String: Any] { | |
if let access_token = dic["access_token"] as? String, | |
let openid = dic["openid"] as? String { | |
getUserInfo(access_token: access_token, openid: openid) | |
} else { | |
let errorCode = dic["errcode"] as? Int ?? -1 | |
let errorMessage = (dic["errmsg"] as? String) ?? "返回数据缺少 access_token 和 openid" | |
var newDic = dic | |
newDic[NSLocalizedDescriptionKey] = errorMessage | |
let error = NSError(domain: kErrorDomain, code: errorCode, userInfo: newDic) | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
} | |
} else { | |
let error = NSError(domain: kErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "解析授权信息 JSON 失败"]) | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
} | |
} catch let error as NSError { | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
} | |
}) | |
task.resume() | |
} | |
private static func getUserInfo(access_token: String, openid: String) { | |
let str = "https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@" | |
let urlString = String(format: str, access_token, openid) | |
guard let url = URL(string: urlString) else { | |
let error = NSError(domain: kErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "生成获取用户信息链接失败"]) | |
_failBlock?(nil, error) | |
return | |
} | |
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, _, error) in | |
if let err = error { | |
DispatchQueue.main.async { | |
_failBlock?(nil, err as NSError) | |
} | |
return | |
} | |
guard let resultData = data else { | |
let error = NSError(domain: kErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "获取用户信息未返回数据"]) | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
return | |
} | |
do { | |
if let dic = try JSONSerialization.jsonObject(with: resultData, options: []) as? [String: Any] { | |
if dic["openid"] != nil { | |
DispatchQueue.main.async { | |
_successBlock?(dic) | |
} | |
} else { | |
let errorCode = dic["errcode"] as? Int ?? -1 | |
let errorMessage = (dic["errmsg"] as? String) ?? "返回数据缺少 access_token、openid 和 unionid" | |
var newDic = dic | |
newDic[NSLocalizedDescriptionKey] = errorMessage | |
let error = NSError(domain: kErrorDomain, code: errorCode, userInfo: newDic) | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
} | |
} else { | |
let error = NSError(domain: kErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "解析用户信息 JSON 失败"]) | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
} | |
} catch let error as NSError { | |
DispatchQueue.main.async { | |
_failBlock?(nil, error) | |
} | |
} | |
}) | |
task.resume() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment