你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> AIR Native Extension for iOS 接入第三方sdk 如何實現 AppDelegate 生命周期

AIR Native Extension for iOS 接入第三方sdk 如何實現 AppDelegate 生命周期

編輯:IOS開發綜合

本文將為大家說明AIR Native Extension for IOS 接入第三方sdk 如何實現 AppDelegate 生命周期的說明,具體操作請看面的內容

作者:Panda Fang

出處:http://www.cnblogs.com/lonkiss/p/6492385.html

原創文章,轉載請注明作者和出處,未經允許不可用於商業營利活動

去年到今年做了幾個 IOS上的AIR Native Extension (簡稱 ANE), 痛苦不堪。 ANE 的開發方式早已被前輩吐槽多多 效率低下 浪費生命 嚴重壓低kpi 。體驗過Unity的插件開發, 相比之下真的是爽快多了,效率飙升。

言歸正傳, 痛苦之一就是難以實現AppDelegate 生命周期。關於生命周期實現,其實Android上的 ane 也難搞。下次再寫。如果在 xcode上做一個標准的 IOS App 寫 AppDelegate 很方便, 填函數就行了。 但是在ANE上 沒有暴露這些api給你實現。air 本身是運行在ios上的app ,adobe 實現它的時候自己使用了 delegate 但是卻不暴露給我們使用。 我們使用adobe air sdk做依賴adobe 的框架, 束手束腳, 真的忍不住一邊做一邊罵adobe 。既然adobe air用了 那麼我們就能靠hook了, 下面這篇文章非常值得看

打通Android、IOS、ANE制作流程 - 知其然知其所以然 - 博客頻道 - CSDN.net

接著我將引用這篇文章進行講解

在xcode 中 新建一個 objective-c 文件 取名為 HookUtil , xocde 將生成一個HookUtil.m文件 將文件裡的代碼刪干淨, 復制下面的代碼粘貼進去。但下面的代碼並不能解決問題,真正要知其所以然還是要堅持看完我最後是怎麼解決的。

  1 //
  2 //  HookUtils.m
  3 //  ResearchMethodSwizzl
  4 //
  5 //  Created by 薛旻 on 15/4/27.
  6 //  Copyright (c) 2015年 薛旻. All rights reserved.
  7 //
  8 
  9 #import <Foundation/Foundation.h>
 10 #import <UIKit/UIKit.h>
 11 #import <objc/runtime.h>
 12 
 13 
 14 @interface HookUtils : NSObject
 15 
 16 + (void)hookMehod:(SEL)oldSEL andDef:(SEL)defaultSEL andNew:(SEL)newSEL;
 17 
 18 @end
 19 
 20 @implementation HookUtils
 21 
 22 + (void)hookMehod:(SEL)oldSEL andDef:(SEL)defaultSEL andNew:(SEL)newSEL {
 23     NSLog(@"hookMehod");
 24 
 25     Class oldClass = objc_getClass([@"CTAppDelegate" UTF8String]);
 26 
 27     Class newClass = [HookUtils class];
 28 
 29     //把方法加給原Class
 30     class_addMethod(oldClass, newSEL, class_getMethodImplementation(newClass, newSEL), nil);
 31     class_addMethod(oldClass, oldSEL, class_getMethodImplementation(newClass, defaultSEL),nil);
 32 
 33     Method oldMethod = class_getInstanceMethod(oldClass, oldSEL);
 34     assert(oldMethod);
 35     Method newMethod = class_getInstanceMethod(oldClass, newSEL);
 36     assert(newMethod);
 37     method_exchangeImplementations(oldMethod, newMethod);
 38 
 39 }
 40 
 41 + (void)load {
 42     NSLog(@"load");
 43     [self hookMehod:@selector(application:didFinishLaunchingWithOptions:) andDef:@selector(defaultApplication:didFinishLaunchingWithOptions:) andNew:@selector(hookedApplication:didFinishLaunchingWithOptions:)];
 44 
 45     [self hookMehod:@selector(applicationWillEnterForeground:) andDef:@selector(defaultApplicationWillEnterForeground:) andNew:@selector(hookedApplicationWillEnterForeground:)];
 46 }
 47 
 48 
 49 /*具體要走的代碼*/
 50 -(BOOL)hookedApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)dic
 51 {
 52     NSLog(@"applicationDidFinishLaunching");
 53     [self hookedApplication:application didFinishLaunchingWithOptions:dic];
 54     return YES;
 55 }
 56 
 57 - (void)hookedApplicationWillResignActive:(UIApplication *)application {
 58     [self hookedApplicationWillResignActive:application];
 59 }
 60 
 61 - (void)hookedApplicationDidEnterBackground:(UIApplication *)application {
 62     [self hookedApplicationDidEnterBackground:application];
 63 }
 64 
 65 - (void)hookedApplicationWillEnterForeground:(UIApplication *)application {
 66     [self hookedApplicationWillEnterForeground:application];
 67 }
 68 
 69 - (void)hookedApplicationDidBecomeActive:(UIApplication *)application {
 70     [self hookedApplicationDidBecomeActive:application];
 71 }
 72 
 73 - (void)hookedApplicationWillTerminate:(UIApplication *)application {
 74     [self hookedApplicationWillTerminate:application];
 75 }
 76 
 77 /*支付寶對應的方法*/
 78 - (BOOL)hookedApplication:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
 79     [self hookedApplication:application openURL:url sourceApplication:sourceApplication annotation:annotation];
 80     return YES;
 81 }
 82 
 83 
 84 
 85 -(BOOL)hookedApplication:(UIApplication*)application handleOpenURL:(NSURL*)url {
 86     [self hookedApplication:application handleOpenURL:url];
 87     return YES;
 88 }
 89 
 90 
 91 #pragma 默認
 92 /*default 默認不需要改動*/
 93 - (BOOL)defaultApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)dic { return YES;
 94 }
 95 
 96 - (void)defaultApplicationWillResignActive:(UIApplication *)application {}
 97 
 98 - (void)defaultApplicationDidEnterBackground:(UIApplication *)application {}
 99 
100 - (void)defaultApplicationWillEnterForeground:(UIApplication *)application {}
101 
102 - (void)defaultApplicationDidBecomeActive:(UIApplication *)application {}
103 
104 - (void)defaultApplicationWillTerminate:(UIApplication *)application {}
105 
106 - (BOOL)defaultApplication:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
107     return YES;
108 }
109 
110 - (BOOL)defaultApplication:(UIApplication *)application handleOpenURL:(NSURL *)url {
111     return YES;
112 }
113 @end

關於這個HookUtils做幾點說明:① HookUtils是IOS的Hook機制的實現,所以適用於所有IOS的開發,這裡只是針對Air應用做了一些處理。① Hook機制中需要獲取應用的實現了生命周期的類名,這樣才能Hook處理,如果你是Xcode工程開發的代碼那你會很方便的找到這個類名,這適用於IOS原生,Unity以及Cocos引擎,因為它們都會使用Xcode開發工具。但是,Air開發是在Flash Builder上,並不直接涉及到Xcode工程,通過代碼打印Air應用的生命周期類,找到了Air的類名CTAppDelegate,於是代碼中設置為,其他引擎自行修改,當然,你也可以通過配置文件(Info.plist)獲取,這樣代碼就不需要修改了

 Class oldClass = objc_getClass([@"CTAppDelegate" UTF8String]);

③ 你需要在hooked**方法中實現你的具體代碼,最後在+ (void)load()方法中調用頭文件定義的方法(void)hookMehod:(SEL)oldSEL andDef:(SEL)defaultSEL andNew:(SEL)newSEL;來達到Hook的目的

上面是引用那篇博客的,我加好代碼後就疑問了, 那哪裡來調用它呢。 問了有經驗的iOS開發者才明白其實並不用在別的函數裡面來調用這個HookUtil裡的函數, 這個類方法 load就是入口, 只要聲明為類方法並起名load會被系統自動調用。 制作好ane 後在demo中測試,原本可以跑起來的demo自從加了HookUtil反而啟動就閃退了,通過觀察log發現 hookMethod執行了,果然是系統自動調用這些代碼, ane 還沒在demo中通過按鈕觸發實例化呢

於是增加log 最後定位到在34行assert(oldMethod); 這行掛掉,原來 oldMethod是null ,但是看半天沒看出來哪裡錯了, 後來懷疑25行oldClass 會不會也是null 呢, 於是加了日志NSLog(@"oldclass %@", oldClass); 果然 也是null , 這時候回顧那篇博客,也許不是CTAppDelegate 這個名字呢? 那篇博客說通過代碼打印Air應用的生命周期類,找到了Air的類名CTAppDelegate。 於是在 hookMethod裡面打印

1    id delegate = [UIApplication sharedApplication].delegate;
2     NSLog(@"delegate %@", delegate);

然而還是null ,然後又想啊, 會不會是時機太早啊。 於是放在了 ane的一個api方法裡面在 應用層demo中通過按鈕觸發,

1 FREObject initSDK(FREContext ctx, void *data, uint32_t argc, FREObject argv[])
2 {
3     id delegate = [UIApplication sharedApplication].delegate;
4     NSLog(@"------------delegate %@", delegate);
5 }

果然不再是null 了, 打印出來的名字也不是CTAppDelegate,而是 CTAppController 我的 airsdk 是21 ,adobe adobe 又改名字了。 把25行代碼中的CTAppDelegate 改成CTAppController 之後測試, delegate中的函數得到正確調用, 實現生命周期delegate就此解決

以上就是這篇文章的全部內容了,希望大家能夠喜歡。

【AIR Native Extension for iOS 接入第三方sdk 如何實現 AppDelegate 生命周期】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved