参考微信官方文档:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html
pod 'WechatOpenSDK'
#import "WXApiObject.h"
#import "WXApi.h"
导入这些:SystemConfiguration.framework,libz.tbd,libsqlite3.0.tbd,libc++.tbd,libWeChatSDK.a即可
在"Other Linker Flags"中加入"-ObjC -all_load"。注:可单独导入 -force_load $(PROJECT_DIR)/Pods/WechatOpenSDK/WeChatSDK1.8.6.1/libWeChatSDK.a(自己libWeChatSDK.a文件路径)
AppDelegate配置
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//微信注册
WXApi.registerApp(“wxAppId”, universalLink:“wxUniversalLink”)
return true
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
return WXApi.handleOpenUniversalLink(userActivity, delegate: self)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let urlKey: String = options[UIApplication.OpenURLOptionsKey.sourceApplication] as! String
return WXApi.handleOpen(url, delegate: self)
}
代理WXApiDelegate,只有微信分享不需要写任何内容
func onReq(_ req: BaseReq) {
//onReq是微信终端向第三方程序发起请求,要求第三方程序响应。第三方程序响应完后必须调用sendRsp返回。在调用sendRsp返回时,会切回到微信终端程序界面。
}
func onResp(_ resp: BaseResp) {
//如果第三方程序向微信发送了sendReq的请求,那么onResp会被回调。sendReq请求调用后,会切到微信终端程序界面。
if resp.errCode == 0 {
//微信授权返回信息
if let myResp:SendAuthResp = resp as? SendAuthResp,let code = myResp.code {
//NotificationCenter通知传递返回的code,有疑虑可查看NotificationCenter使用方法
NotificationCenter.default.post(name: NSNotification.Name("wxAuthNotifyKey"), object: nil, userInfo: ["code" : code])
}
}
}
微信分享
/*会话, 朋友圈, 收藏*/
enum LDShareType {
case Session, Timeline, Favorite
}
//分享文本
func shareText(_ text: String, to scene: LDShareType) {
let req = SendMessageToWXReq()
req.text = text
req.bText = true
switch scene {
case .Session:
req.scene = Int32(WXSceneSession.rawValue)
case .Timeline:
req.scene = Int32(WXSceneTimeline.rawValue)
case .Favorite:
req.scene = Int32(WXSceneFavorite.rawValue)
}
//
WXApi.send(req)
}
备注:1、ShareWebPageModel 是我自建的Model,2、图片链接需先下载图片转UIImage后再分享,3、图片需压缩到30k以下分享内容才显示小图标,压缩方法网上自己找吧
//分享网页
func shareWebPage(_ model: ShareWebPageModel, to scene: LDShareType) {
//缩略图处理
var thumb: UIImage?
if let image = model.thumbImage {
thumb = image
} else {
if let url = model.thumbImageUrl,url != "",let urlURL = URL(string: url) {
//图片url转UIImage
ImageDownloader.default.downloadImage(with: urlURL, retrieveImageTask: nil, options: nil, progressBlock: nil) { (image, error, ur, _) in
if let img = image {
model.thumbImage = img
} else {
model.thumbImageUrl = ""
}
self.shareWebPage(model, to: scene)
}
return
}
}
let webpageObject = WXWebpageObject()
webpageObject.webpageUrl = model.webpageUrl
let message = WXMediaMessage()
message.title = model.title
message.description = model.description
if let image = thumb {
//print("开始压缩图片:\(model.isReduce)")
if model.isReduce {
let img = ImageTools.reduceImg(sourceImage: image, maxImageLenght: 150, maxSizeKB: 30)
message.setThumbImage(img)
} else {
message.setThumbImage(image)
}
}
//
message.mediaObject = webpageObject
let req = SendMessageToWXReq()
req.bText = false
req.message = message
switch scene {
case .Session:
req.scene = Int32(WXSceneSession.rawValue)
case .Timeline:
req.scene = Int32(WXSceneTimeline.rawValue)
case .Favorite:
req.scene = Int32(WXSceneFavorite.rawValue)
}
//
WXApi.send(req) { (status) in
print(status)
}
}
微信授权登陆,注意:NetworkTools.GetNull是自己封装的get方法(可使用自己项目已有的get方法替换)
//发起微信授权请求
func sendAuthRequest() {
if WXApi.isWXAppInstalled() {
let req = SendAuthReq()
req.scope = "snsapi_userinfo"
req.state = "fangdianstate"
WXApi.send(req, completion: nil)
} else {
print("请先安装微信!")
}
}
//MARK:使用code获取access_token和openid
func getAuthInfo(code: String, finishedCallback: @escaping (_ result : Any) -> ()) {
/*返回实例:下面的参数都有删减,使用自己的参数
{
"access_token": "8OVqz3f8JVEDEwTlFJozDeIR3WHvZWPVeZZkuJ1xoqJsGjmrPrgL7e3AEkRGg2FQ8bSmIgf85",
"expires_in": 700,
"refresh_token": "RBEMo5D0yirHuxODrcUslcFZG5DZWJlArz_wZEnxllTlZssfTTTw_qexxqZfCHr0qBLTagOkFvU9C2Lg2R708oyHw8Bw32FENdPjwA",
"openid": "I",
"scope": "snserinfo",
"unionid": "CBhHOXTVqSM34bvLB4wk"
}
access_token有效期为2个小时
refresh_token拥有较长的有效期(30天)当refresh_token失效的后,需要用户重新授权。
*/
NetworkTools.GetNull("https://api.weixin.qq.com/sns/oauth2/access_token?", parameters: ["appid":wxAppId as Any,"secret": wxSecret as Any, "code": code as Any, "grant_type": "authorization_code"]) { (result) in
if let resultDict = result as? [String: Any] {
//print(resultDict)
if let accessToken = resultDict["access_token"] as? String, let wxOpenID = resultDict["openid"] as? String {
self.setUserInfo(accessToken: accessToken, wxOpenID: wxOpenID, finishedCallback: { (res) in
finishedCallback(res)
})
} else {
finishedCallback(["error": 1, "errmsg": "授权失败"])
}
} else {
finishedCallback(["error": 1, "errmsg": "授权失败"])
}
}
}
//MARK:使用access_token和openid获取用户信息
func setUserInfo(accessToken: String, wxOpenID: String, finishedCallback: @escaping (_ result : Any) -> ()) {
/*返回实例
{
"openid": "ovH_u0aLE02ZBPEGtJBI",
"nickname": "111",
"sex": 0,
"language": "zh_CN",
"city": "",
"province": "",
"country": "CN",
"headimgurl": "http://wx.qlogo.cn/mpen/icF4iau8Sj7b2dwmVjtU1x153dqWOrDdMksichtT9ttGsxUkicRVNRKMl2tIFZ80EHFnBNeaPjGlrczBYHHr1fQgPp18nMv11111111aHd1/0",
"privilege": [],
"unionid": "oicxf1C0JOXTVqSM34bk123444"
}
*/
//拿到用户信息,登录授权成功
NetworkTools.GetNull("https://api.weixin.qq.com/sns/userinfo?", parameters: ["access_token": accessToken as Any,"openid": wxOpenID as Any]) { (result) in
if let resultDict = result as? [String: Any] {
//print(resultDict)
finishedCallback(resultDict)
} else {
finishedCallback(["error": 1, "errmsg": "未获取到用户信息"])
}
}
}
发起授权登陆
//点击微信登陆
@IBAction func wxLoginBtnClicked(_ sender: Any) {
AppDelegate.shared.sendAuthRequest()
//监听接收消息,获取传过来的code,触发微信登陆方法
NotificationCenter.default.addObserver(self, selector: #selector(wxLogin(noti:)), name: NSNotification.Name(rawValue: "wxAuthNotifyKey"), object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc private func wxLogin(noti: Notification) {
guard let userinfo = noti.userInfo as? [String: Any] else {
return
}
guard let code = userinfo["code"] as? String else {
return
}
//使用消息中心获取到的code,获取用户的微信授权信息
AppDelegate.shared.getAuthInfo(code: code) { (result) in
guard let resultDict = result as? [String: Any] else {
self.recoverWxLoginStatus(true, false)
return
}
print("微信用户信息:\(resultDict)")
//微信登陆
//...
}
}