iOS实时发版,动态库方式 不上App Store可以使用啊
iOS如果想要实现实时发版,据我了解现在基本上用的是两种方式
1:使用Lua脚本进行,基本上很多手游都是这样做的,再配合上Cocos2d-x这个框架使用起来也比较简单。
2:使用动态库 这里我说的就是这中方式。
先说下实现思路,在动态库中实现一个入口类,和入口方法,这个方法在主工程中调用
这里说下创建动态库的步骤:
下面直接上代码啦。
动态库中测试界面
VCOne.h
#import <UIKit/UIKit.h> @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 <Foundation/Foundation.h> @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的目录下
这里在记录下如果找到编译出来的静态库。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。