• 通知(Notification) 、 应用间通信(一)


    1 使用通知中心发送消息

    1.1 问题

    当一个对象需要向多个接受者发送消息的,或者不用知道消息的接收者是谁,就可以使用IOS提供的NSNotificationCenter通知中心,本案例使NSNotificationCenter通知中心改变界面上所有按钮的颜色,如图-1所示:

    图-1

    1.2 方案

    首先在创建好的Xcode项目的Storyboard中拖放两个场景,其中第一个场景带有NavigationController,这两个场景分别和ViewController类以及ChangeColorViewController进行绑定,这两个类全都继承至UIViewController。

    在第一个场景中拖放一个Button控件,标题设置为ChangeColor,选中Button控件按住Control键往第二个场景拖拽,实现第一个场景跳转到第二个场景,跳转模式选择Push。

    在第二个场景上拖放三个Button控件,标题分别设置为Blue、Red和Yellow,代表各自的颜色,并将这三个按钮关联成ChangeColorViewController的同一个方法chooseColor:。

    其次实现ChangeColorViewController类中的chooseColor:方法,该方法的功能就是根据用户选择的颜色,使用postNotificationName:object:userInfo:方法进行发通知,该方法中需要将用户选择的颜色通过userInfo传递给通知的接受者。

    然后创建一个TRButton类继承至UIButton,重写init初始化方法,按钮是通知的接受者,需要在init方法中使用addObserver:selector:name:object:进行注册通知,name参数是通知名字,这里命名为ChangeColor,selector参数是当接受到通知时调用的方法,这里定义一个方法changeColor:,该方法的功能就是改变按钮的颜色,该方法的参数是NSNotification类型的对象,记录着通知发送者传递过来的信息。

    实现changeColor方法,该方法中通过NSNotification类型的参数obj的useInfo属性获取到用户选择的颜色,根据用户选择的颜色修改按钮的背景色。

    最后在ViewController类中的viewDidLoad方法中用代码创建三个TRButton类型的按钮,运行程序即可根据用户的选择统一修改三个按钮的背景颜色。

    1.3 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:搭建Storyboard界面

    首先在创建好的Xcode项目的Storyboard中拖放两个场景,其中第一个场景带有NavigationController,这两个场景分别和ViewController类以及ChangeColorViewController进行绑定,这两个类全都继承至UIViewController。

    在第一个场景中拖放一个Button控件,标题设置为ChangeColor,选中Button控件按住Control键往第二个场景拖拽,实现第一个场景跳转到第二个场景,跳转模式选择Push。

    在第二个场景上拖放三个Button控件,标题分别设置为Blue、Red和Yellow,代表各自的颜色,并将这三个按钮关联成ChangeColorViewController的同一个方法chooseColor:,Storyboard中的界面如图-2所示:

    图-2

    步骤二:实现chooseColor:方法

    实现ChangeColorViewController类中的chooseColor:方法,该方法的功能就是根据用户选择的颜色,使用postNotificationName:object:userInfo:方法进行发送通知,name参数是通知的名字,userInfo是一个NSDictionary类型的参数,记录着需要传递给通知接受者的信息。

    chooseColor:方法中需要将用户选择的颜色通过userInfo传递给通知的接受者,代码如下所示:

    1. - (IBAction)chooseColor:(UIButton *)sender {
    2. NSString *title = sender.titleLabel.text;
    3. [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeColor" object:nil userInfo:@{@"color":title}];
    4. }

    步骤三:创建TRButton类

    首先创建一个TRButton类继承至UIButton,然后重写init初始化方法,按钮是通知的接受者,需要在init方法中使用addObserver:selector:name:object:进行注册通知,name参数是通知的名字,需要和发送的通知名字保持一致,所以这里命名为ChangeColor,selector参数是当接受到通知时调用的方法,这里定义一个方法changeColor:,代码如下所示:

    1. - (instancetype)init
    2. {
    3. self = [super init];
    4. if (self) {
    5. [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    6. [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeColor:) name:@"ChangeColor" object:nil];
    7. }
    8. return self;
    9. }

    changeColor:方法的功能就是改变按钮的颜色,该方法的参数是一个NSNotification类型的对象,记录着通知发送者传递过来的信息。可以根据NSNotification类型的参数的useInfo属性获取到用户选择的颜色,根据用户选择的颜色修改按钮的背景色,代码如下所示:

    1. -(void)changeColor:(NSNotification*)obj{
    2. NSString *title = [obj.userInfo valueForKey:@"color"];
    3. if([title isEqualToString:@"Blue"])
    4. {
    5. [self setBackgroundColor:[UIColor blueColor]];
    6. }else if([title isEqualToString:@"Red"]){
    7. [self setBackgroundColor:[UIColor redColor]];
    8. }else {
    9. [self setBackgroundColor:[UIColor yellowColor]];
    10. }
    11. }

    步骤四:创建TRButton按钮

    在ViewController类中的viewDidLoad方法中用代码创建三个TRButton类型的按钮,并设置相关属性,代码如下所示:

     
    1. - (void)viewDidLoad {
    2. [super viewDidLoad];
    3. TRButton *btn1 = [[TRButton alloc]init];
    4. [btn1 setFrame:CGRectMake(100, 100, 100, 50)];
    5. [btn1 setTitle:@"btn1" forState:UIControlStateNormal];
    6. [self.view addSubview:btn1];
    7. TRButton *btn2= [[TRButton alloc]init];
    8. [btn2 setFrame:CGRectMake(100, 170, 100, 50)];
    9. [btn2 setTitle:@"btn2" forState:UIControlStateNormal];
    10. [self.view addSubview:btn2];
    11. TRButton *btn3 = [[TRButton alloc]init];
    12. [btn3 setFrame:CGRectMake(100, 240, 100, 50)];
    13. [btn3 setTitle:@"btn3" forState:UIControlStateNormal];
    14. [self.view addSubview:btn3];
    15. }

    运行程序即可根据用户的选择统一修改三个按钮的背景颜色。

    1.4 完整代码

    本案例中,ViewController.m文件中的完整代码如下所示:

     
    1. #import "ViewController.h"
    2. #import "TRButton.h"
    3. @implementation ViewController
    4. - (void)viewDidLoad {
    5. [super viewDidLoad];
    6. TRButton *btn1 = [[TRButton alloc]init];
    7. [btn1 setFrame:CGRectMake(100, 100, 100, 50)];
    8. [btn1 setTitle:@"btn1" forState:UIControlStateNormal];
    9. [self.view addSubview:btn1];
    10. TRButton *btn2= [[TRButton alloc]init];
    11. [btn2 setFrame:CGRectMake(100, 170, 100, 50)];
    12. [btn2 setTitle:@"btn2" forState:UIControlStateNormal];
    13. [self.view addSubview:btn2];
    14. TRButton *btn3 = [[TRButton alloc]init];
    15. [btn3 setFrame:CGRectMake(100, 240, 100, 50)];
    16. [btn3 setTitle:@"btn3" forState:UIControlStateNormal];
    17. [self.view addSubview:btn3];
    18. }
    19. @end
     

    本案例中,ChangeColorViewController.m文件中的完整代码如下所示:

     
    1. #import "ChangeColorViewController.h"
    2. @implementation ChangeColorViewController
    3. - (IBAction)chooseColor:(UIButton *)sender {
    4. NSString *title = sender.titleLabel.text;
    5. [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeColor" object:nil userInfo:@{@"color":title}];
    6. }
    7. @end
     

    本案例中,ChangeColorViewController.m文件中的完整代码如下所示:

     
    1. #import "TRButton.h"
    2. @implementation TRButton
    3. - (instancetype)init
    4. {
    5. self = [super init];
    6. if (self) {
    7. [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    8. [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeColor:) name:@"ChangeColor" object:nil];
    9. }
    10. return self;
    11. }
    12. -(void)changeColor:(NSNotification*)obj{
    13. NSString *title = [obj.userInfo valueForKey:@"color"];
    14. if([title isEqualToString:@"Blue"])
    15. {
    16. [self setBackgroundColor:[UIColor blueColor]];
    17. }else if([title isEqualToString:@"Red"]){
    18. [self setBackgroundColor:[UIColor redColor]];
    19. }else {
    20. [self setBackgroundColor:[UIColor yellowColor]];
    21. }
    22. }
    23. @end

    2 通过UIActivityViewController实现应用间的通信

    2.1 问题

    UIActivity是IOS6提供的一个十分有用的控件,可以十分方便的将文字、图片等内容进行分享,比如分享到微信、新浪微博、发邮件、发短信给等,也可以通过自定义按钮实现定制功能,本案例通过UIActivityViewController和自定义Activity实现应用间的通信,如图-3所示:

    图-3

    2.2 方案

    首先在创建好的Xcode项目的Storyboard中拖放一个TextField控件和两个Button控件,将两个Button的标题设置为“分享”和“自定义”,将textField控件关联成ViewController的属性textField,两个Button关联成ViewController的方法share和customActivity。

    其次在share方法中创建UIActivityViewController对象,使用初始化方法initWithActivityItems:applicationActivities:进行初始化,activityItems是一个NSArray类型的参数,代表执行activity中用到的数据对象数组,applicationActivities参数是一个UIActivity对象的数组,代表了应用程序支持的自定义服务,这个参数可以是nil。

    这里share方法中直接使用系统提供的服务即可,可以通过设置excludedActivityTypes属性去掉不需要包含的服务,然后通过present方法显示出来。

    然后实现customActivity方法,该方法中提供自定义服务,所以首先需要自定义一个服务,即创建一个TRStringReverseActivity继承至UIActivity,提供自定义服务将需要处理的字符串数据进行反转。在TRStringReverseActivity类中重写父类的方法实现弹出对话框,显示反转字符串的需求。

    最后实现customActivity方法,该方法中创建UIActivityViewController对象,然后创建一组NSArray类型的字符串对象itemsToShare和TRStringReverseActivity对象stringReverseActivity,分别作为activityItems参数和applicationActivities参数,然后通过present方法显示出来。

    2.3 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:搭建Storyboard界面

    首先在创建好的Xcode项目的Storyboard中拖放一个TextField控件和两个Button控件,将两个Button的标题设置为“分享”和“自定义”,将textField控件关联成ViewController的属性textField,两个Button关联成ViewController的方法share和customActivity,Storyboard中的界面如图-4所示:

    图-4

    步骤二:实现share方法

    首先在share方法中创建UIActivityViewController对象,使用初始化方法initWithActivityItems:applicationActivities:进行初始化,activityItems是一个NSArray类型的参数,代表执行activity中用到的数据对象数组,applicationActivities参数是一个UIActivity对象的数组,代表了应用程序支持的自定义服务,这个参数可以是nil,代码如下所示:

     
    1. - (IBAction)shared
    2. {
    3. UIActivityViewController * activityVC = [[UIActivityViewController alloc]initWithActivityItems:@[self.textField.text] applicationActivities:nil];
    4. }

    然后设置excludedActivityTypes属性去掉不需要包含的服务,通过present方法显示出来,代码如下所示:

    1. - (IBAction)shared
    2. {
    3. UIActivityViewController * activityVC = [[UIActivityViewController alloc]initWithActivityItems:@[self.textField.text] applicationActivities:nil];
    4. //设置不包含的activity
    5. activityVC.excludedActivityTypes = @[UIActivityTypeCopyToPasteboard];
    6. [self presentViewController:activityVC animated:YES completion:nil];
    7. }

    运行程序点击分享按钮,从应用底部出现分享框,如图-5所示:

    图-5

    点击Mail服务按钮,程序自动跳转到Mall应用,如图-6所示:

    图-6

    步骤三:创建自定义服务类

    首先创建一个TRStringReverseActivity继承至UIActivity,提供自定义服务将需要处理的字符串数据进行反转。

    其次在TRStringReverseActivity类中重写父类的方法activityType、activityTitle和activityImage设置服务的类型、标题和图片,代码如下所示:

    1. //服务的类型
    2. - (NSString *)activityType
    3. {
    4. return [[NSBundle mainBundle].bundleIdentifier stringByAppendingFormat:@".%@", NSStringFromClass([self class])];
    5. }
    6. //显示在分享框中的服务的名称
    7. - (NSString *)activityTitle
    8. {
    9. return @"返转";
    10. }
    11. //显示在分享框的服务的图片
    12. - (UIImage *)activityImage
    13. {
    14. return [UIImage imageNamed:@"random"];
    15. }

    然后通过重写父类的方法canPerformWithActivityItems:、prepareWithActivityItems:和performActivity设置服务按钮的显示、解析数据和实现相应的自定义服务功能,代码如下所示:

     
    1. //是否显示服务按钮
    2. - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
    3. {
    4. for (id object in activityItems) {
    5. if ([object isKindOfClass:[NSString class]]) {
    6. return YES;
    7. }
    8. }
    9. return NO;
    10. }
    11. //解析服务数据时调用
    12. - (void)prepareWithActivityItems:(NSArray *)activityItems
    13. {
    14. NSMutableArray *stringObjects = [[NSMutableArray alloc]init];
    15. for (id object in activityItems) {
    16. if ([object isKindOfClass:[NSString class]]) {
    17. [stringObjects addObject:object];
    18. }
    19. }
    20. self.activityItems = stringObjects;
    21. }
    22. //执行服务,根据自己的应用做相应的处理
    23. - (void)performActivity
    24. {
    25. NSMutableString *reverseStrings = [[NSMutableString alloc]init];
    26. //反转字符串
    27. for (NSString *string in self.activityItems) {
    28. [reverseStrings appendString:[self reverseString:string]];
    29. [reverseStrings appendString:@" "];
    30. }
    31. UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"字符串返转" message:reverseStrings delegate:self cancelButtonTitle:@"确定" otherButtonTitles: nil];
    32. [alert show];
    33. }

    最后实现一个字符串反转的方法reverseString:,代码如下所示:

    1. - (NSString *)reverseString:(NSString *)paramString
    2. {
    3. NSMutableString *reversed = [[NSMutableString alloc]init];
    4. for (NSInteger counter = paramString.length - 1; counter>=0; counter--) {
    5. [reversed appendFormat:@"%c", [paramString characterAtIndex:counter]];
    6. }
    7. return [reversed copy];
    8. }

    步骤四:实现customActivity方法

    首先customActivity方法中创建一组NSArray类型的字符串对象itemsToShare和TRStringReverseActivity对象stringReverseActivity,代码如下所示:

     
    1. - (IBAction)customActivity
    2. {
    3. NSArray *itemsToShare = @[@"Hello", @"World", @"Haha", @"123456789"];
    4. TRStringReverseActivity *stringReverseActivity = [[TRStringReverseActivity alloc]init];
    5. }

    然后创建UIActivityViewController对象,使用initWithActivityItems: applicationActivities:方法进行初始化,itemsToShare对象和stringReverseActivity对象分别作为activityItems参数和applicationActivities参数,最后通过present方法显示出来,代码如下所示:

     
    1. - (IBAction)customActivity
    2. {
    3. NSArray *itemsToShare = @[@"Hello", @"World", @"Haha", @"123456789"];
    4. TRStringReverseActivity *stringReverseActivity = [[TRStringReverseActivity alloc]init];
    5. UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:itemsToShare applicationActivities:@[stringReverseActivity]];
    6. [self presentViewController:activityVC animated:YES completion:nil];
    7. }

    运行程序点击自定义按钮,从应用底部出现分享框,如图-7所示:

    图-7

    点击返转服务按钮,界面弹出alertView对话框,并将字符串返转显示出来,如图-8所示:

    图-8

    2.4 完整代码

    本案例中,TRViewController.m文件中的完整代码如下所示:

     
    1. #import "TRViewController.h"
    2. #import "TRStringReverseActivity.h"
    3. @interface TRViewController ()
    4. @property (weak, nonatomic) IBOutlet UITextField *textField;
    5. @end
    6. @implementation TRViewController
    7. - (IBAction)shared
    8. {
    9. UIActivityViewController * activityVC = [[UIActivityViewController alloc]initWithActivityItems:@[self.textField.text] applicationActivities:nil];
    10. //设置不包含的activity
    11. activityVC.excludedActivityTypes = @[UIActivityTypeCopyToPasteboard];
    12. [self presentViewController:activityVC animated:YES completion:nil];
    13. }
    14. - (IBAction)customActivity
    15. {
    16. NSArray *itemsToShare = @[@"Hello", @"World", @"Haha", @"123456789"];
    17. TRStringReverseActivity *stringReverseActivity = [[TRStringReverseActivity alloc]init];
    18. UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:itemsToShare applicationActivities:@[stringReverseActivity]];
    19. [self presentViewController:activityVC animated:YES completion:nil];
    20. }
    21. @end
     

    本案例中,TRStringReverseActivity.m文件中的完整代码如下所示:

     
    1. #import "TRStringReverseActivity.h"
    2. @interface TRStringReverseActivity () <UIAlertViewDelegate>
    3. @property (strong, nonatomic) NSMutableArray *activityItems;
    4. @end
    5. @implementation TRStringReverseActivity
    6. //服务的类型
    7. - (NSString *)activityType
    8. {
    9. return [[NSBundle mainBundle].bundleIdentifier stringByAppendingFormat:@".%@", NSStringFromClass([self class])];
    10. }
    11. //显示在分享框中的服务的名称
    12. - (NSString *)activityTitle
    13. {
    14. return @"返转";
    15. }
    16. //显示在分享框的服务的图片
    17. - (UIImage *)activityImage
    18. {
    19. return [UIImage imageNamed:@"random"];
    20. }
    21. //是否显示分享按钮
    22. - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
    23. {
    24. for (id object in activityItems) {
    25. if ([object isKindOfClass:[NSString class]]) {
    26. return YES;
    27. }
    28. }
    29. return NO;
    30. }
    31. //解析分享数据时调用
    32. - (void)prepareWithActivityItems:(NSArray *)activityItems
    33. {
    34. NSMutableArray *stringObjects = [[NSMutableArray alloc]init];
    35. for (id object in activityItems) {
    36. if ([object isKindOfClass:[NSString class]]) {
    37. [stringObjects addObject:object];
    38. }
    39. }
    40. self.activityItems = stringObjects;
    41. }
    42. //执行服务,根据自己的应用做相应的处理
    43. - (void)performActivity
    44. {
    45. NSMutableString *reverseStrings = [[NSMutableString alloc]init];
    46. //反转字符串
    47. for (NSString *string in self.activityItems) {
    48. [reverseStrings appendString:[self reverseString:string]];
    49. [reverseStrings appendString:@" "];
    50. }
    51. UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"字符串返转" message:reverseStrings delegate:self cancelButtonTitle:@"确定" otherButtonTitles: nil];
    52. [alert show];
    53. }
    54. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    55. {
    56. [self activityDidFinish:YES];
    57. }
    58. - (NSString *)reverseString:(NSString *)paramString
    59. {
    60. NSMutableString *reversed = [[NSMutableString alloc]init];
    61. for (NSInteger counter = paramString.length - 1; counter>=0; counter--) {
    62. [reversed appendFormat:@"%c", [paramString characterAtIndex:counter]];
    63. }
    64. return [reversed copy];
    65. }
    66. @end
     

    3 使用URL实现应用间的通信

    3.1 问题

    如果一个应用程序支持一些已知类型的URL,就可以通过对应的URL模式和该程序进行通讯,本案例使用URL实现应用间的通信,如图-9所示:

    图-9

    3.2 方案

    首先在创建一个项目iac_source,在Storyboard场景中拖放一个Button控件,标题设置为“go to target”,并将Button关联成ViewController的方法click:。在click:方法中先制定一个通信的url类型iac。

    其次创建一个项目iac_target,在项目配置的plist文件中声明支持url类型为iac,即iac_source中定义的url类型。

    然后在程序iac_source中的viewDidLoad方法中使用UIApplication的openURL:方法实现应用间的跳转,URL是一个NSURL类型的参数。

    最后在程序iac_target中响应,通过程序iac_source传递过来的URL信息在方法application:openURL:sourceApplication:annotation:中解析,该方法每次运行程序时都会被调用。

    3.3 步骤

    实现此案例需要按照如下步骤进行。

    步骤一:定义url类型

    首先在创建一个项目iac_source,在Storyboard场景中拖放一个Button控件,标题设置为“go to target”,并将Button关联成ViewController的方法click:。在click:方法中先制定一个通信的url类型iac,代码如下所示:

     
    1. - (IBAction)click:(UIButton *)sender {
    2. NSURL *url = [NSURL URLWithString:@"iac://function/addContact?name=apple&age=18"];
    3. }

    步骤二:在目标应用中声明支持的url类型

    首先创建一个项目iac_target,在项目配置的plist文件中声明支持url类型为iac,即iac_source中定义的url类型。

    展开 resources选择<app>info.plist,鼠标右击information property list ,然后从列表中选择URL types,右击 add row 添加一个对象(item)右击item add row ,从列表中选URL Schemes 再右击添加一个对象(item0),将item0的值设置为iac,如图-10所示:

    图-10

    步骤三:实现应用间的跳转

    在程序iac_source中的viewDidLoad方法中使用UIApplication的openURL:方法实现应用间的跳转,代码如下所示:

     
    1. - (IBAction)click:(UIButton *)sender {
    2. NSURL *url = [NSURL URLWithString:@"iac://function/addContact?name=apple&age=18"];
    3. [[UIApplication sharedApplication]openURL:url];
    4. }

    步骤四:响应并解析数据

    在程序iac_target中响应,通过程序iac_source传递过来的URL信息在方法application:openURL:sourceApplication:annotation:中解析,openURL参数就是传递过来的url信息,该方法每次运行程序时都会被调用。

    本案例实现根据传递过来的url参数,修改界面上Label的显示内容,首先在iac_target项目中的Storyboard界面拖拽一个Label控件,并关联成ViewController的属性name,代码如下所示:

    1. @interface ViewController ()
    2. @property (weak, nonatomic) IBOutlet UILabel *name;
    3. @end

    其次在AppDelegate里面定义一个NSString类型的属性name,代码如下所示:

     
    1. @interface AppDelegate : UIResponder <UIApplicationDelegate>
    2. @property (strong, nonatomic) UIWindow *window;
    3. @property (nonatomic,copy)NSString *name;
    4. @end

    然后在ViewController类中使用观察者模式,监听AppDelegate的name属性的改变,当name属性发生改变时,就修改界面Label的显示内容,代码如下所示:

     
    1. -(void)viewWillAppear:(BOOL)animated {
    2. [super viewWillAppear:animated];
    3. self.app = [UIApplication sharedApplication].delegate;
    4. self.name.text = self.app.name;
    5. [self.app addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    6. }
    7. -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    8. self.name.text = self.app.name;
    9. }
    10. -(void)viewWillDisappear:(BOOL)animated {
    11. [self.app removeObserver:self forKeyPath:@"name"];
    12. }

    最后application:openURL:sourceApplication:annotation:方法解析url数据,获取到url中的参数信息,修改name属性的值,代码如下所示:

     
    1. -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    2. if ([[url scheme] isEqualToString:@"iac"]) {
    3. NSMutableDictionary * parasDict = [@{} mutableCopy];
    4. //获取url的参数
    5. NSString * query = [url query];
    6. //将参数字符串用“&”分割
    7. NSArray * paras = [query componentsSeparatedByString:@"&"];
    8. //每一个参数用“=”分割
    9. for (NSString * para in paras) {
    10. NSArray * paraItems = [para componentsSeparatedByString:@"="];
    11. NSString * key = paraItems[0];
    12. NSString * value = paraItems[1];
    13. [parasDict setObject:value forKey:key];
    14. }
    15. //修改name属性
    16. self.name = [parasDict valueForKey:@"name"];
    17. }
    18. return YES;
    19. }

    3.4 完整代码

    本案例中,iac_source项目中的ViewController.m文件中的完整代码如下所示:

    1. #import "ViewController.h"
    2. @implementation ViewController
    3. - (IBAction)click:(UIButton *)sender {
    4. NSURL *url = [NSURL URLWithString:@"iac://function/addContact?name=apple&age=18"];
    5. [[UIApplication sharedApplication]openURL:url];
    6. }
    7. @end

    本案例中,iac_target项目中的AppDelegate.h文件中的完整代码如下所示:

     
    1. #import <UIKit/UIKit.h>
    2. @interface AppDelegate : UIResponder <UIApplicationDelegate>
    3. @property (strong, nonatomic) UIWindow *window;
    4. @property (nonatomic,copy)NSString *name;
    5. @end
     

    本案例中,iac_target项目中的AppDelegate.m文件中的完整代码如下所示:

     
    1. #import "AppDelegate.h"
    2. @implementation AppDelegate
    3. -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    4. if ([[url scheme] isEqualToString:@"iac"]) {
    5. NSMutableDictionary * parasDict = [@{} mutableCopy];
    6. //获取url的参数
    7. NSString * query = [url query];
    8. //将参数字符串用“&”分割
    9. NSArray * paras = [query componentsSeparatedByString:@"&"];
    10. //每一个参数用“=”分割
    11. for (NSString * para in paras) {
    12. NSArray * paraItems = [para componentsSeparatedByString:@"="];
    13. NSString * key = paraItems[0];
    14. NSString * value = paraItems[1];
    15. [parasDict setObject:value forKey:key];
    16. }
    17. //修改name属性
    18. self.name = [parasDict valueForKey:@"name"];
    19. }
    20. return YES;
    21. }
    22. @end
     

    本案例中,iac_target项目中的ViewController.m文件中的完整代码如下所示:

     
    1. #import "ViewController.h"
    2. #import "AppDelegate.h"
    3. @interface ViewController ()
    4. @property (weak, nonatomic) IBOutlet UILabel *name;
    5. @property (nonatomic,assign)AppDelegate *app;
    6. @end
    7. @implementation ViewController
    8. -(void)viewWillAppear:(BOOL)animated {
    9. [super viewWillAppear:animated];
    10. self.app = [UIApplication sharedApplication].delegate;
    11. self.name.text = self.app.name;
    12. [self.app addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    13. }
    14. -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    15. self.name.text = self.app.name;
    16. }
    17. -(void)viewWillDisappear:(BOOL)animated {
    18. [self.app removeObserver:self forKeyPath:@"name"];
    19. }
    20. @end
  • 相关阅读:
    样式问题
    布局
    通用模板实现可变参数函数
    使用单例模式实习string类
    动态生成一维数组和二维数组
    自定义的类传数据到主窗口控件上的方法
    使用TableView
    G480折腾上了黑苹果,完美了,哈哈
    error C2383: 此符号中不允许有默认参数
    动态链接库的隐式动态链接和显示动态链接
  • 原文地址:https://www.cnblogs.com/52190112cn/p/5049498.html
Copyright © 2020-2023  润新知