diff --git a/README.en.md b/README.en.md deleted file mode 100644 index d177f2e..0000000 --- a/README.en.md +++ /dev/null @@ -1,97 +0,0 @@ -# The Introduction of EMControllerManager - -## Purpose -It's a common scenario that we want to push a view controller inside another view controller. Assume that we have `ViewController1` and `ViewController2`. Now, we want to push `ViewController2` when a button in the `ViewController1` is touched. A standard practice would be: - -ViewController1: - - #import "ViewController2.h" - ... - - (void)buttonPushOnTouch:(id)sender { - ... - ViewController2 *vc2 = [[ViewController2 alloc]init]]; - [self.navigationViewController pushViewController:vc2 animate:YES]; - } - -In this situation, `ViewController1` should know the existence of `ViewController2` before it can alloc one. Therefore, they are tightly coupled and hardly to reuse. - -With EMControllerManager, you can write code like: - -ViewController1: - - ... - - (void)buttonPushOnTouch:(id)sender { - ... - EMControllerManager *cm = [EMControllerManager sharedInstance]; - UIViewController *vc2 = [cm createViewControllerInstanceNamed:@"ViewController2" withPropertyValues:@{@"color":[UIColor redColor],@"number":@(1)}]; // The name follows your config file, not necessarily ViewController2. - [self.navigationViewController pushViewController:vc2 animate:YES]; - } - -In this way, `ViewController1` doesn't need to know `ViewController2`, and you don't need to import `ViewController2.h` into `ViewController1.m` - -## Configuration -The configuration file can be either a JSON file or a plist file. Take JSON file as an example, a typical configuration code should be like this: - - { - "Test1":{ - "ClassName":"Test1ViewController", - "Description":"The homepage of the app", - "Tag":"100", - "Dependencies":{ - "dependentString":"@Yes, you can inject a string using the config file", - "dependentInt":1000, - "dependentBool":true, - "test2ViewController":"Test2" - } - }, - "Test2":"Test2ViewController" - } - -* `Test1` and `Test2` are controller names. You can name that as you wish. And when you are using `createViewControllerInstanceNamed:withPropertyValues:`, the parameter `Named` should follow this field. -* `ClassName` is the real class name of the view controller. It should match the interface name. If you fill a wrong value to this field, the `createViewControllerInstanceNamed:withPropertyValues:` is impossible to create an instance (will return `nil`), and you will receive a warning, though this won't crash your app. -* `Description` and `Tag` are optional, actually they are just comments (JSON doesn't support comments, so I have to use a redundant field). -* `Dependencies` are something that can be injected into the new instance. It supports all basic types that are supported both by JSON and Objective C, e.g. string, int, float, bool. Furthermore, you can inject another controller name that are configured in this file. The manager will create an instance of that class and inject it. However, you should pay attention that if you want to inject a string rather than a configured class reference, you need to add an `'@'` as the prefix, otherwise the string will be recognized as the controller name of another configured class. Also, a recursive dependency is not allowed. - -You can use a plist instead, the rules are the same as that for JSON. - -## Additional configuration -Besides configuration files, you can add configurations dynamically in your code. - -Here is an example: - - [cm addViewControllerConfigWithBlock:^(NSMutableDictionary *extraNameClassMapping) { - - EMControllerConfigItem *item1 = [[EMControllerConfigItem alloc]init]; - item1.controllerClassName = @"Test3ViewController"; - - EMControllerConfigItem *item2 = [[EMControllerConfigItem alloc]init]; - item2.controllerClass = [Test4ViewController class]; - - [extraNameClassMapping setObject:item1 forKey:@"Test3"]; - [extraNameClassMapping setObject:item2 forKey:@"Test4"]; - }]; - -You create an `EMControllerConfigItem`, then add it into the given mutable dictionary. Notice that you should at least assign one of `controllerClassName` and `controllerClass`. And if `controllerClass` is assigned, then `controllerClassName` will be omited. - -Again, you can add dependencies into an item. The rule is the same as above. - -## Usage - -A piece of typical code is like - -In AppDelegate.m: - - EMControllerManager *cm = [EMControllerManager sharedInstance]; - NSString *path = [[NSBundle mainBundle]pathForResource:@"ViewControllerConfig" ofType:@"json"]; - NSError *e = nil; - [cm loadConfigFileOfPath:path fileType:EMControllerManagerConfigFileTypeJSON error:&e]; - if (e) { - NSLog(@"%@",[e localizedDescription]); - } - -In your view controller: - - // Initialize properties using two methods - UIViewController *vc = [cm createViewControllerInstanceNamed:@"Test1" withPropertyValues:@{@"color":[UIColor redColor],@"number":@(1)}]; - -`createViewControllerInstanceNamed:withPropertyValues:` will create an instance of a configured class. You can pass a dictionary through `PropertyValues`. How these values are handled depends on the instance. If it conforms the `EMControllerManagerInitProtocol` and responds to `initializePropertiesWithDictionary:`, then this method will be called. Otherwise, the values in the dictionary will be injected into the instance directly by KVC. diff --git a/README.md b/README.md index 6feb439..d177f2e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# EMControllerManager使用说明 +# The Introduction of EMControllerManager -## 用途 -用于iOS中对UIViewController进行解耦。比如ViewController1需要push ViewController2,标准写法是: +## Purpose +It's a common scenario that we want to push a view controller inside another view controller. Assume that we have `ViewController1` and `ViewController2`. Now, we want to push `ViewController2` when a button in the `ViewController1` is touched. A standard practice would be: ViewController1: @@ -13,9 +13,9 @@ ViewController1: [self.navigationViewController pushViewController:vc2 animate:YES]; } -此时,ViewController1和ViewController2就是紧密耦合了。不易于复用。 +In this situation, `ViewController1` should know the existence of `ViewController2` before it can alloc one. Therefore, they are tightly coupled and hardly to reuse. -如果使用EMControllerManager,则代码如下: +With EMControllerManager, you can write code like: ViewController1: @@ -23,22 +23,22 @@ ViewController1: - (void)buttonPushOnTouch:(id)sender { ... EMControllerManager *cm = [EMControllerManager sharedInstance]; - UIViewController *vc2 = [cm createViewControllerInstanceNamed:@"ViewController2" withPropertyValues:@{@"color":[UIColor redColor],@"number":@(1)}]; // 这里的name根据配置文件来,不一定是ViewController2 + UIViewController *vc2 = [cm createViewControllerInstanceNamed:@"ViewController2" withPropertyValues:@{@"color":[UIColor redColor],@"number":@(1)}]; // The name follows your config file, not necessarily ViewController2. [self.navigationViewController pushViewController:vc2 animate:YES]; } -这样一来,ViewController1就不需要知道任何ViewController2的任何信息了。 +In this way, `ViewController1` doesn't need to know `ViewController2`, and you don't need to import `ViewController2.h` into `ViewController1.m` -## 配置文件 -配置文件可以是JSON格式,也可以是plist。以JSON格式为例,一个典型的配置文件如下: +## Configuration +The configuration file can be either a JSON file or a plist file. Take JSON file as an example, a typical configuration code should be like this: { "Test1":{ "ClassName":"Test1ViewController", - "Description":"hahahahahhahaha", + "Description":"The homepage of the app", "Tag":"100", "Dependencies":{ - "dependentString":"@hahahahahah", + "dependentString":"@Yes, you can inject a string using the config file", "dependentInt":1000, "dependentBool":true, "test2ViewController":"Test2" @@ -47,19 +47,17 @@ ViewController1: "Test2":"Test2ViewController" } -其中 +* `Test1` and `Test2` are controller names. You can name that as you wish. And when you are using `createViewControllerInstanceNamed:withPropertyValues:`, the parameter `Named` should follow this field. +* `ClassName` is the real class name of the view controller. It should match the interface name. If you fill a wrong value to this field, the `createViewControllerInstanceNamed:withPropertyValues:` is impossible to create an instance (will return `nil`), and you will receive a warning, though this won't crash your app. +* `Description` and `Tag` are optional, actually they are just comments (JSON doesn't support comments, so I have to use a redundant field). +* `Dependencies` are something that can be injected into the new instance. It supports all basic types that are supported both by JSON and Objective C, e.g. string, int, float, bool. Furthermore, you can inject another controller name that are configured in this file. The manager will create an instance of that class and inject it. However, you should pay attention that if you want to inject a string rather than a configured class reference, you need to add an `'@'` as the prefix, otherwise the string will be recognized as the controller name of another configured class. Also, a recursive dependency is not allowed. -* `Test1`被成为`Controller Name`,和`createViewControllerInstanceNamed:withPropertyValues:`中的`name`相对应。 -* `ClassName`是这个view controller的类名,如果在这边写了一个错误的名称,则create时不能生成对应实体(返回nil)。 -* `Description`和`Tag`是辅助字段,可有可无。 -* `Dependencies`是依赖关系注入,是个Dictionary,里面的key为目标view controller的一个property,value可以是string, int, float, bool等基本类型,也可以是配置文件里面的另一个`Controller Name`,如本例里面的`"test2ViewController":"Test2"`。**需要注意**:如果希望注入的是一个简单的string,则string必须以'@'开头,否则会被当做配置文件里面的另一个Controller Name。 +You can use a plist instead, the rules are the same as that for JSON. -另外,你也可以使用plist,规则和JSON是一样的。 +## Additional configuration +Besides configuration files, you can add configurations dynamically in your code. -## 额外配置 -除配置文件之外,还可以在程序中动态增加配置。 - -例如: +Here is an example: [cm addViewControllerConfigWithBlock:^(NSMutableDictionary *extraNameClassMapping) { @@ -73,12 +71,16 @@ ViewController1: [extraNameClassMapping setObject:item2 forKey:@"Test4"]; }]; -其中,一个config item中,`controllerClassName`和`controllerClass`必须有其中一个,否则将被视为无效配置。一个config item可以有用Dictionary组成的dependencies,规则和配置文件中一样。 +You create an `EMControllerConfigItem`, then add it into the given mutable dictionary. Notice that you should at least assign one of `controllerClassName` and `controllerClass`. And if `controllerClass` is assigned, then `controllerClassName` will be omited. + +Again, you can add dependencies into an item. The rule is the same as above. + +## Usage + +A piece of typical code is like -## 使用 -典型的使用代码: +In AppDelegate.m: - // In application:didFinishLaunchingWithOptions: EMControllerManager *cm = [EMControllerManager sharedInstance]; NSString *path = [[NSBundle mainBundle]pathForResource:@"ViewControllerConfig" ofType:@"json"]; NSError *e = nil; @@ -86,11 +88,10 @@ ViewController1: if (e) { NSLog(@"%@",[e localizedDescription]); } - - //======================================================= - - // In a view controller + +In your view controller: + // Initialize properties using two methods UIViewController *vc = [cm createViewControllerInstanceNamed:@"Test1" withPropertyValues:@{@"color":[UIColor redColor],@"number":@(1)}]; -其中,`createViewControllerInstanceNamed:withPropertyValues:`中的`propertyValues`是一个Dictionary,用于对目标controller的property注入。当目标view controller实现了`EMControllerManagerInitProtocol`,则会去调用目标view controller的`initializePropertiesWithDictionary:`方法,否则直接用KVC注入。 +`createViewControllerInstanceNamed:withPropertyValues:` will create an instance of a configured class. You can pass a dictionary through `PropertyValues`. How these values are handled depends on the instance. If it conforms the `EMControllerManagerInitProtocol` and responds to `initializePropertiesWithDictionary:`, then this method will be called. Otherwise, the values in the dictionary will be injected into the instance directly by KVC. diff --git a/README.zh.md b/README.zh.md new file mode 100644 index 0000000..6feb439 --- /dev/null +++ b/README.zh.md @@ -0,0 +1,96 @@ +# EMControllerManager使用说明 + +## 用途 +用于iOS中对UIViewController进行解耦。比如ViewController1需要push ViewController2,标准写法是: + +ViewController1: + + #import "ViewController2.h" + ... + - (void)buttonPushOnTouch:(id)sender { + ... + ViewController2 *vc2 = [[ViewController2 alloc]init]]; + [self.navigationViewController pushViewController:vc2 animate:YES]; + } + +此时,ViewController1和ViewController2就是紧密耦合了。不易于复用。 + +如果使用EMControllerManager,则代码如下: + +ViewController1: + + ... + - (void)buttonPushOnTouch:(id)sender { + ... + EMControllerManager *cm = [EMControllerManager sharedInstance]; + UIViewController *vc2 = [cm createViewControllerInstanceNamed:@"ViewController2" withPropertyValues:@{@"color":[UIColor redColor],@"number":@(1)}]; // 这里的name根据配置文件来,不一定是ViewController2 + [self.navigationViewController pushViewController:vc2 animate:YES]; + } + +这样一来,ViewController1就不需要知道任何ViewController2的任何信息了。 + +## 配置文件 +配置文件可以是JSON格式,也可以是plist。以JSON格式为例,一个典型的配置文件如下: + + { + "Test1":{ + "ClassName":"Test1ViewController", + "Description":"hahahahahhahaha", + "Tag":"100", + "Dependencies":{ + "dependentString":"@hahahahahah", + "dependentInt":1000, + "dependentBool":true, + "test2ViewController":"Test2" + } + }, + "Test2":"Test2ViewController" + } + +其中 + +* `Test1`被成为`Controller Name`,和`createViewControllerInstanceNamed:withPropertyValues:`中的`name`相对应。 +* `ClassName`是这个view controller的类名,如果在这边写了一个错误的名称,则create时不能生成对应实体(返回nil)。 +* `Description`和`Tag`是辅助字段,可有可无。 +* `Dependencies`是依赖关系注入,是个Dictionary,里面的key为目标view controller的一个property,value可以是string, int, float, bool等基本类型,也可以是配置文件里面的另一个`Controller Name`,如本例里面的`"test2ViewController":"Test2"`。**需要注意**:如果希望注入的是一个简单的string,则string必须以'@'开头,否则会被当做配置文件里面的另一个Controller Name。 + +另外,你也可以使用plist,规则和JSON是一样的。 + +## 额外配置 +除配置文件之外,还可以在程序中动态增加配置。 + +例如: + + [cm addViewControllerConfigWithBlock:^(NSMutableDictionary *extraNameClassMapping) { + + EMControllerConfigItem *item1 = [[EMControllerConfigItem alloc]init]; + item1.controllerClassName = @"Test3ViewController"; + + EMControllerConfigItem *item2 = [[EMControllerConfigItem alloc]init]; + item2.controllerClass = [Test4ViewController class]; + + [extraNameClassMapping setObject:item1 forKey:@"Test3"]; + [extraNameClassMapping setObject:item2 forKey:@"Test4"]; + }]; + +其中,一个config item中,`controllerClassName`和`controllerClass`必须有其中一个,否则将被视为无效配置。一个config item可以有用Dictionary组成的dependencies,规则和配置文件中一样。 + +## 使用 +典型的使用代码: + + // In application:didFinishLaunchingWithOptions: + EMControllerManager *cm = [EMControllerManager sharedInstance]; + NSString *path = [[NSBundle mainBundle]pathForResource:@"ViewControllerConfig" ofType:@"json"]; + NSError *e = nil; + [cm loadConfigFileOfPath:path fileType:EMControllerManagerConfigFileTypeJSON error:&e]; + if (e) { + NSLog(@"%@",[e localizedDescription]); + } + + //======================================================= + + // In a view controller + // Initialize properties using two methods + UIViewController *vc = [cm createViewControllerInstanceNamed:@"Test1" withPropertyValues:@{@"color":[UIColor redColor],@"number":@(1)}]; + +其中,`createViewControllerInstanceNamed:withPropertyValues:`中的`propertyValues`是一个Dictionary,用于对目标controller的property注入。当目标view controller实现了`EMControllerManagerInitProtocol`,则会去调用目标view controller的`initializePropertiesWithDictionary:`方法,否则直接用KVC注入。