通知(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:@"\n"];
  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:@"\n"];
  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
时间: 2024-10-27 05:12:48

通知(Notification) 、 应用间通信(一)的相关文章

【转】VC 线程间通信的三种方式

原文网址:http://my.oschina.net/laopiao/blog/94728 1.使用全局变量(窗体不适用)      实现线程间通信的方法有很多,常用的主要是通过全局变量.自定义消息和事件对象等来实现的.其中又以对全局变量的使用最为简洁.该方法将全局变量作为线程监视的对象,并通过在主线程对此变量值的改变而实现对子线程的控制.      由于这里的全局变量需要在使用它的线程之外对其值进行改变,这就需要通过volatile关键字对此变量进行说明.使用全局变量进行线程通信的方法非常简单

线程同步--线程间通信

一.线程同步 线程的同步方法跟其他系统下类似,我们可以用原子操作,可以用 mutex,lock 等. iOS 的原子操作函数是以 OSAtomic 开头的,比如:OSAtomicAdd32, OSAtomicOr32 等等.这些函数可以直接使用,因为它 们是原子操作. iOS 中的 mutex 对应的是 NSLock,它遵循 NSLooking 协议,我们可以使用 lock, tryLock, lockBeforeData:来加锁,用 unLock 来解锁.使用示例: BOOL moreToDo

java多线程系列5-死锁与线程间通信

这篇文章介绍java死锁机制和线程间通信 死锁 死锁:两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象. 同步代码块的嵌套案例 public class MyLock { // 创建两把锁对象 public static final Object objA = new Object(); public static final Object objB = new Object(); } public class DieLock extends Thread { private b

架构设计:系统间通信(15)——服务治理与Dubbo 上篇

1.上篇中"自定义服务治理框架"的问题 在之前的文章中(<架构设计:系统间通信(13)--RPC实例Apache Thrift 下篇(1)>.<架构设计:系统间通信(14)--RPC实例Apache Thrift 下篇(2)>),我们基于服务治理的基本原理,自己实现了一个基于zookeeper + thrift的服务治理框架.但实际上前文中我们自行设计的服务治理框架除了演示基本原理外,并没有多大的实际使用价值,因为还有很多硬性需求是没有实现的: 访问权限:在整个

线程间通信与同步

线程间通信的两个基本问题是互斥和同步. 同步:一个线程的执行依赖于另一个线程的消息. 互斥:对共享资源的排他性,一个线程必须等待别的线程释放公共资源之后才能继续执行. 同步机制(Win32中):事件,信号量,互斥量,临界区 各种同步方式: #全局变量 win32多线程通信的最方式,但用全局变量同步会有两个弊端,应该避免 >主线程没有进入休眠状态,依然会消耗CPU资源 >如果主线程优先级比ThreadFunc高,则全局变量无法在ThreadFunc中被改变,这样线程无法得到通知 #事件 由于ev

Java笔记七.线程间通信与线程生命的控制

线程间通信与线程生命的控制 一.线程通信方法 Java是通过Object类的wait.notify.notifyAll这几个方法来实现进程键的通信.由于所有的类都是从Object继承的,因此在任何类中都可以直接使用这些方法. wait:告诉当前线程放弃监视器并进入睡眠状态,知道其他线程进入同一监视器并调用notify为止; notify:唤醒同一对象监视器中调用wait的第一个线程.用于类似饭馆有一个空位后通知所有等候就餐的顾客中的第一位可以入座的情况: notifyAll:唤醒同一对象监视器中

进程间通信和线程间通信

进程间通信: # 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系通常是指父子进程关系.# 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信.# 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问.它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源.因此,主要作为进程间以及同一进程内不同线程之间的同步手段.#

架构设计:系统间通信(43)——自己动手设计ESB(4)

============================== 接上文<架构设计:系统间通信(42)--自己动手设计ESB(3)> 5.Borker Server选择 在本文之前的三篇文章中,我们介绍了自行设计的ESB中间件的顶层设计.介绍了主控服务如何对多个ESB-Brokers动态节点进行日志采集和监控.还介绍了ESB-Broker节点如何进行动态路由定义的加载管理.这篇文章我们主要讨论关于ESB-Client的一些关键设计. 在我们自行设计的ESB中间件中为了保证ESB服务不会成为整个软件

架构设计:系统间通信(5)——IO通信模型和JAVA实践 下篇

接上篇:<架构设计:系统间通信(4)--IO通信模型和JAVA实践 中篇>,我们继续讲解 异步IO 7.异步IO 上面两篇文章中,我们分别讲解了阻塞式同步IO.非阻塞式同步IO.多路复用IO 这三种IO模型,以及JAVA对于这三种IO模型的支持.重点说明了IO模型是由操作系统提供支持,且这三种IO模型都是同步IO,都是采用的"应用程序不询问我,我绝不会主动通知"的方式. 异步IO则是采用"订阅-通知"模式:即应用程序向操作系统注册IO监听,然后继续做自己

Android中线程间通信原理分析:Looper,MessageQueue,Handler

自问自答的两个问题 在我们去讨论Handler,Looper,MessageQueue的关系之前,我们需要先问两个问题: 1.这一套东西搞出来是为了解决什么问题呢? 2.如果让我们来解决这个问题该怎么做? 以上者两个问题,是我最近总结出来的,在我们学习了解一个新的技术之前,最好是先能回答这两个问题,这样你才能对你正在学习的东西有更深刻的认识. 第一个问题:google的程序员们搞出这一套东西是为了解决什么问题的?这个问题很显而易见,为了解决线程间通信的问题.我们都知道,Android的UI/Vi