8

How do I do authorization and login with WeChat using the iOS SDK? There doesn't seem to be much information about this on stack overflow or google and most of the documents are in Chinese.

Kex
  • 8,023
  • 9
  • 56
  • 129

2 Answers2

11

Choosing to answer my own question here as there seems to be lack of information about this on stack overflow and google. I hope others also find it useful.

1.) Follow Suragch's excellent answer on how to setup the iOS SDK: How to add the WeChat API to a Swift project?. Make sure AppDelegate is setup as described with the func onReq(req: BaseReq!) and func onResp(resp: BaseResp!) methods implemented.

2.) To get login and authorization working you MUST download and use the Chinese version of the SDK. Curiously some of the functions needed to login are removed from the English version. Chinese SDK here: https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319164&lang=zh_CN

3.) Firstly we want to authorize the app we want to use with WeChat. This can be done like so:

let req = SendAuthReq()
req.scope = "snsapi_userinfo" //Important that this is the same
req.state = "co.company.yourapp_wx_login" //This can be any random value
WXApi.sendReq(req)

This should return a code to func onResp(resp: BaseResp!) I implemented the method like so - triggering a notification:

func onResp(resp: BaseResp!) {
        if let authResp = resp as? SendAuthResp {
            if authResp.code != nil {
                let dict = ["response": authResp.code]
                NSNotificationCenter.defaultCenter().postNotificationName("WeChatAuthCodeResp", object: nil, userInfo: dict)             
            } else {                    
                let dict = ["response": "Fail"]
                NSNotificationCenter.defaultCenter().postNotificationName("WeChatAuthCodeResp", object: nil, userInfo: dict)                    
            }                
        } else {                
            let dict = ["response": "Fail"]
            NSNotificationCenter.defaultCenter().postNotificationName("WeChatAuthCodeResp", object: nil, userInfo: dict)
        }
    }

4.) With the code we can now try and get the openID and the accessToken. To do this we need to build a link using the appID, appSecret and do a HTTP GET request. The appID and appSecret are details you get when you register the app with WeChat. Example like so:

private let appID = "somecode2132113"
private let appSecret = "someappsecret213123"

private let accessTokenPrefix = "https://api.weixin.qq.com/sns/oauth2/access_token?"

private func buildAccessTokenLink(withCode code: String) -> String {
        return accessTokenPrefix + "appid=" + appID + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code"
    }

With this link we can perform a HTTP GET request and obtain the openID and accessToken in the JSON. (Try it in Postman). I won't post the code for this, but I'm using Alamofire.

5.) Finally we can go one step further and try to get the WeChat user's nickname and profile photo. Very similar to before we create a new link using the openID and accessToken we obtained in the step before. Like so:

private let userInfoPrefix = "https://api.weixin.qq.com/sns/userinfo?"

private func buildUserInfoLink(withOpenID openID: String, accessToken: String) -> String {
        return userInfoPrefix + "access_token=" + accessToken + "&openid=" + openID
    }

Again, perform a HTTP GET request and the JSON will return the nickname and profile photo link!

plus: detailed guide here: http://www.kekearif.com/how-to-implement-ios-wechat-login/

haxpor
  • 2,431
  • 3
  • 27
  • 46
Kex
  • 8,023
  • 9
  • 56
  • 129
  • 1
    I have tried following your steps but when I am navigated to WeChat app for authorisation, I keep getting the message: **Oops! Something went wrong :(** I checked the logs in Xcode and I am not getting anything other than the error code -2 in the response object. Any tips? – Kushal Ashok Aug 16 '16 at 12:54
  • @KushalAshok have you checked the wechat portal page? Make sure you have the correct credentials, app ID etc as what you are seeing is an error from their end. – Kex Aug 17 '16 at 10:02
  • 1
    I checked the we chat account and learned that I need to pay 300 CNY for an audit, post which the login API will be enabled for my app. – Kushal Ashok Aug 18 '16 at 03:23
  • @Kex does the first HTTP get request represent a deep link which opens the WeChat app for the user to log in? and then the response function is the call back which we chat calls in the calling app? Sorry trying to visualize how this will look from the experience of a user – Thalatta Aug 22 '16 at 19:40
  • You might wanna add some code to check wechat is installed too before doing that first call. – Kex Aug 23 '16 at 16:07
  • great! Thank you Kex! – Thalatta Aug 24 '16 at 00:04
  • @KushalAshokdid you find out what was wrong ? Have the same issue here. – jfgrang Oct 31 '16 at 15:55
  • last link (kekearif.com) seems dead – Fonix May 04 '17 at 09:12
  • I'm skipping [this review](https://stackoverflow.com/review/suggested-edits/16751310) because I don't know Chinese. If the link being changed is indeed outdated and the new link is correct you may want to accept the edit. – BSMP Jul 19 '17 at 01:27
  • Why am i getting error for using "WXApi.sendReq(req)" -> (Compiler Suggest to change 'WXApi.send(req)')---- i need help – Muhammad Asyraf Feb 06 '18 at 10:20
  • NSNotificationCenter.defaultCenter().postNotificationName("WeChatAuthCodeResp", object: nil, userInfo: dict) give me error on "dict" as extra argument was called – Muhammad Asyraf Feb 06 '18 at 10:26
1

I've done everything following accepted answer, but it just didn't worked, until I've changed my Info.plist

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>weixin</string>
    </array>

to

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>weixin</string>
        <string>weixinULAPI</string>
    </array>

Got it from official guide here

Dmytro Rostopira
  • 10,588
  • 4
  • 64
  • 86