ios 动态库热更新 可以上app store么
1个回答
2016-08-03
展开全部
iOS如果想要实现实时发版,据我了解现在基本上用的是两种方式
1:使用Lua脚本进行,基本上很多手游都是这样做的,再配合上Cocos2d-x这个框架使用起来也比较简单。
2:使用动态库 这里我说的就是这中方式。
先说下实现思路,在动态库中实现一个入口类,和入口方法,这个方法在主工程中调用
这里说下创建动态库的步骤:
下面直接上代码啦。
动态库中测试界面
VCOne.h
?
1
2
3
4
5
6
#import <uikit uikit.h="">
@interface VCOne :UIViewController
@property (retain, nonatomic) NSBundle *root_bundle;//保存framework的路径
@end</uikit>
VCOne.m
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (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
?
1
2
3
4
5
6
7
8
9
10
11
#import <foundation foundation.h="">
@interface FrameWorkStart : NSObject
/*
* 主程序和此动态库的关系枢纽,也就是从“主程序”到“动态库内封装的程序”的入口方法
*/
- (void) startWithObject:(id)object withBundle:(NSBundle *)bundle;
@end</foundation>
FrameWorkStart.m
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#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的目录下
1:使用Lua脚本进行,基本上很多手游都是这样做的,再配合上Cocos2d-x这个框架使用起来也比较简单。
2:使用动态库 这里我说的就是这中方式。
先说下实现思路,在动态库中实现一个入口类,和入口方法,这个方法在主工程中调用
这里说下创建动态库的步骤:
下面直接上代码啦。
动态库中测试界面
VCOne.h
?
1
2
3
4
5
6
#import <uikit uikit.h="">
@interface VCOne :UIViewController
@property (retain, nonatomic) NSBundle *root_bundle;//保存framework的路径
@end</uikit>
VCOne.m
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (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
?
1
2
3
4
5
6
7
8
9
10
11
#import <foundation foundation.h="">
@interface FrameWorkStart : NSObject
/*
* 主程序和此动态库的关系枢纽,也就是从“主程序”到“动态库内封装的程序”的入口方法
*/
- (void) startWithObject:(id)object withBundle:(NSBundle *)bundle;
@end</foundation>
FrameWorkStart.m
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#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的目录下
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询