序

本文源于今天早上@清望同學(xué)遇到的一個(gè)問(wèn)題。
需求
項(xiàng)目需求需要使用兩個(gè)不同的微信appid授權(quán),進(jìn)行不同的操作。
appid1: 用于微信授權(quán)進(jìn)行賬號(hào)登錄。
appid2: 用于微信授權(quán)進(jìn)行微信取現(xiàn)。
問(wèn)題
獲取appid2授權(quán)時(shí),可能跳轉(zhuǎn)到appid1的授權(quán)頁(yè)。
分析
微信授權(quán)

// 1. 注冊(cè)
[WXApi registerApp:WEIXIN_APP_ID];
// 2. 請(qǐng)求授權(quán)
SendAuthReq *auth = [[SendAuthReq alloc] init];
auth.scope = @"snsapi_userinfo";
auth.state = @"UUID";
[WXApi sendAuthReq:auth viewController:nil delegate:self];
// 3. 處理請(qǐng)求結(jié)果
[WXApi handleOpenURL:url delegate:self];
以上是微信的授權(quán)流程。由于兩次請(qǐng)求授權(quán)使用不同的key。所以每次請(qǐng)求之前都重新初始化。但是沒(méi)有跳轉(zhuǎn)到相應(yīng)appid的授權(quán)。
猜測(cè)
由于是授權(quán)頁(yè)沒(méi)有調(diào)轉(zhuǎn)到相應(yīng)appid的授權(quán)頁(yè)。
所以猜測(cè)[WXApi registerApp:WEIXIN_APP_ID];接口重新初始化,appid沒(méi)有改變
驗(yàn)證猜測(cè)
由于請(qǐng)求授權(quán)[WXApi sendAuthReq:auth viewController:nil delegate:self]; 內(nèi)部最終會(huì)調(diào)用UIApplication的
- (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options completionHandler:(void (^ __nullable)(BOOL success))completion接口。
我們可以注入鉤子代碼查看這里的url值是否使用正確的appid。
[[UIApplication sharedApplication] aspect_hookSelector:@selector(openURL:options:completionHandler:) withOptions:AspectPositionBefore usingBlock:^(id aspectInfo) {
// 打印微信URL參數(shù)
NSLog(@"%@: %@", aspectInfo.instance, aspectInfo.arguments);
} error:NULL];
注入方法
- 使用runtime。這種方法需要額外手工寫(xiě)代碼注入方法。
- 使用Aspects。使用比較簡(jiǎn)單。源碼地址 https://github.com/steipete/Aspects
解決問(wèn)題
確認(rèn)是由于[WXApi registerApp:WEIXIN_APP_ID];接口重新初始化后,并沒(méi)有修改相應(yīng)的appid。
那么我們做相應(yīng)的修改來(lái)確保重新初始化appid。
方法一:使用runtime直接修改微信內(nèi)部屬性值。
我沒(méi)有采用這種方法。如果你做了,可以告訴我怎么做 :)
方法二:修改UIApplication的openURL函數(shù)調(diào)用時(shí)的url值,修改為正確的appid。
#define WEIXIN_APP_ID_1 @"微信appid1"
#define WEIXIN_APP_ID_2 @"微信appid2"
[[UIApplication sharedApplication] aspect_hookSelector:@selector(openURL:options:completionHandler:) withOptions:AspectPositionInstead usingBlock:^(id<AspectInfo> aspectInfo) {
NSLog(@"%@: %@", aspectInfo.instance, aspectInfo.arguments);
// 修改url中相應(yīng)的appid參數(shù)。
NSInvocation *invocation = info.originalInvocation;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"weixin://app/%@/auth/?scope=snsapi_userinfo&state=%@", WEIXIN_APP_ID_2,weakSelf.reqKey]];
[invocation setArgument:&url atIndex:2];
[invocation retainArguments];
[invocation invoke];
} error:NULL];
總結(jié)
- 微信sdk初始化,再次初始化不會(huì)改變相應(yīng)的appid值。也沒(méi)有提供反初始化接口。
- 采用鉤子的方法,驗(yàn)證猜想。
- 使用runtime修復(fù)問(wèn)題。
后續(xù)
微信SDK內(nèi)部還可能存儲(chǔ)上一次的授權(quán)信息。也需要清除??纯聪挛缯{(diào)試結(jié)果再補(bǔ)充吧……