iOS即時發版,動態庫方式 不上App Store可以使用啊
iOS如果想要實現即時發版,據我瞭解現在基本上用的是兩種方式
1:使用Lua指令碼進行,基本上很多手遊都是這樣做的,再配合上Cocos2d-x這個架構使用起來也比較簡單。
2:使用動態庫 這裡我說的就是這中方式。
先說下實現思路,在動態庫中實現一個入口類,和入口方法,這個方法在主工程中調用
這裡說下建立動態庫的步驟:
下面直接上代碼啦。
動態庫中測試介面
VCOne.h
#import @interface VCOne :UIViewController@property (retain, nonatomic) NSBundle *root_bundle;//儲存framework的路徑@end
VCOne.m
- (void) viewDidLoad{ [super viewDidLoad]; UILabel * label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)]; label1.text = @第一個視圖; [self.view addSubview:label1]; self.view.backgroundColor = [UIColor whiteColor]; UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[_root_bundle pathForResource:@changmen ofType:@jpg]]]; image.frame = CGRectMake(100, 100, 300, 300); [self.view addSubview:image]; }
下面介紹與主工程互動的入口類。
FrameWorkStart.h
#import @interface FrameWorkStart : NSObject/* * 主程式和此動態庫的關係樞紐,也就是從“主程式”到“動態庫內封裝的程式”的入口方法 */- (void) startWithObject:(id)object withBundle:(NSBundle *)bundle;@end
FrameWorkStart.m
#import FrameWorkStart.h#import VCOne.h@implementation FrameWorkStart- (void) startWithObject:(id)object withBundle:(NSBundle *)bundle{ /* *初始化第一個controller *這裡的重點是資源檔的載入 通常我們在初始化的時候並不是很在意bundle:這個參數, 其實我們所用到的圖片、xib等資源檔都是在程式內部中擷取的,也就是我們常用的[NSBundle mainBundle]中擷取,所謂的NSBundle本質上就是一個路徑,mainBundle指向的是.app下。 而如果我們不指定bundle,則會預設從.app路徑下去尋找資源。 不過很顯然,我們的動態庫是放到“主程式”的document檔案下的,所以資源檔是不可能在[NSbundle mainBundle]中擷取到的,所以這裡我們需要指定bundle參數,這也是傳遞framework的路徑的意義所在 */ VCOne *vcone = [[VCOne alloc] init]; vcone.root_bundle = bundle; //轉換傳遞過來的mainCon參數,實現介面跳轉 UIViewController *viewCon = (UIViewController *)object; [viewCon presentViewController:vcone animated:YES completion:^{ NSLog(@跳轉到動態更新模組成功!); }]; }
下面是主工程,當然就是建立的普通的iOS工程
ViewController.m
#import ViewController.h@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame = CGRectMake(30, 30, 100, 50); [btn setTitle:@測試動態庫 forState:UIControlStateNormal]; [btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; }- (void) test{ NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); NSString *documentDirectory = nil; if ([paths count] != 0) documentDirectory = [paths objectAtIndex:0]; NSLog(@documentDirectory = %@,documentDirectory); //拼接我們放到document中的framework路徑 NSString *libName = @Test1.framework; NSString *destLibPath = [documentDirectory stringByAppendingPathComponent:libName]; //判斷一下有沒有這個檔案的存在 如果沒有直接跳出 NSFileManager *manager = [NSFileManager defaultManager]; if (![manager fileExistsAtPath:destLibPath]) { NSLog(@There isn't have the file); return; } //複製到程式中 NSError *error = nil; //載入方式二:使用NSBundle載入動態庫 NSBundle *frameworkBundle = [NSBundle bundleWithPath:destLibPath]; if (frameworkBundle && [frameworkBundle load]) { NSLog(@bundle load framework success.); }else { NSLog(@bundle load framework err:%@,error); return; } /* *通過NSClassFromString方式讀取類 *FrameWorkStart 為動態庫中入口類 */ Class pacteraClass = NSClassFromString(@FrameWorkStart); if (!pacteraClass) { NSLog(@Unable to get TestDylib class); return; } /* *初始化方式採用下面的形式 alloc init的形式是行不通的 同樣,直接使用PacteraFramework類初始化也是不正確的 *通過- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; 方法調用入口方法(startWithObject:withBundle:),並傳遞參數(withObject:self withObject:frameworkBundle) */ NSObject *pacteraObject = [pacteraClass new]; [pacteraObject performSelector:@selector(startWithObject:withBundle:) withObject:self withObject:frameworkBundle]; }
將動態庫的工程編譯一下,放入主工程的document的目錄下
這裡在記錄下如果找到編譯出來的靜態庫。