今天在用 ShareSDK 做第三方登錄的時候,發(fā)現使用舊版 SDK 時是在 AppDelegate.m 文件里手動實現 2 個處理客戶端返回消息的回調方法,如下圖
而新版 SDK 卻不需要。那么問題來了,新版是在哪里實現處理客戶端返回消息的回調方法?
要知道,處理回跳必須需要實現以下方法
iOS 9 以下用這個
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
iOS 9 及以上用這個
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
我猜想 ShareSDK 是用 AppDelegate 的分類實現了方法,但一般情況下,在OC中只要分類實現了方法,那么類中的原來實現方法就不會被調用。 而現在這個方法我們可以自定義實現,且不影響第三方客戶端回跳,怎么做???
其實要做到分類方法不覆蓋原方法需要用的 OC 的 Runtime ,來測試一下
在 AppDelegate.m 中實現 applicationDidBecomeActive:
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"applicationDidBecomeActive");
}
再創(chuàng)建一個 AppDelegate 的分類,實現applicationDidBecomeActive:
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"applicationDidBecomeActive--分類");
Class currentClass = [AppDelegate class];
if (currentClass) {
unsigned int methodCount;
Method *methodList = class_copyMethodList(currentClass, &methodCount);
IMP lastImp = NULL;
SEL lastSel = NULL;
for (NSInteger i = 0; i < methodCount; i++) {
Method method = methodList[i];
NSString *methodName = [NSString stringWithCString:sel_getName(method_getName(method))
encoding:NSUTF8StringEncoding];
if ([@"applicationDidBecomeActive:" isEqualToString:methodName]) {
lastImp = method_getImplementation(method);
lastSel = method_getName(method);
}
}
typedef void (*fn)(id,SEL,id);
if (lastImp != NULL) {
fn f = (fn)lastImp;
f(self,lastSel,application);
}
free(methodList);
}
}
打印結果
2017-06-15 21:55:45.709 demo[807:25011] applicationDidBecomeActive--分類
2017-06-15 21:55:45.709 demo[807:25011] applicationDidBecomeActive
這樣,就可以同時調用分類和原類的方法了,不知道 ShareSDK 是不是這樣的思路