2019-03-13 17:21:49 qq_41856760 阅读数 580
  • iOS移动开发从入门到精通(Xcode11 & Swift5)

    【课程特点】 学习iOS开发,请选本套课程,理由如下: 1、180节大容量课程:包含了iOS开发中的大部分实用技能; 2、创新的教学模式:手把手教您iOS开发技术,一看就懂,一学就会; 3、贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标; 4、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间; 【课程内容】 本视频教程拥有180节课程,包含iOS开发的方方面面:iOS开发基础理论知识、 视图、视图控制器、多媒体、数据处理、常用插件、信用卡卡号识别、自动化测试、网络访问、多线程、ShareSDK社会化分享、CoreImage、CoreText、CoreML机器学习、ARKit增强现实、面部检测、Storyboard技巧、关键帧动画、本地通知、陀螺仪相机定位设备、本地化、通过IAP内购实现营利、App上传与审核等超多干货! 

    2571 人正在学习 去看看 李发展

一、通知

通知是iOS中的一种消息传递方式,通过消息中心(NSNotificationCenter)对消息的监听,当某些类发送出消息的时候,消息中心监听到这些消息,然后进行相应的操作,这些操作对于发送出这些消息的类来说是相同的。

下面通过一个demo来说明通知的实现

                                 

就是点击按钮,弹出弹窗,然后点击弹窗中的按钮打印出一些信息。 这个信息是由前面自定义的alertView发出给到控制器的,我们用通知来实现这之间的数据传递。


//viewController.m
- (IBAction)buttonDidClicked:(UIButton *)sender {
    
    LSRAlertView * view = [LSRAlertView alertWithTitle:@"操作完成" andTitleImageName:@"gou"];
    [view addTopButtonWithTitle:@"确定"];
    [view addBottomButtomWithTitle:@"取消"];
    [view show];
    //这里向消息中心注册消息
    //obsever:观察者,谁来监听这个消息
    //selector:监听到发出的对应的消息后要做什么
    //name:监听的消息的名称
    //obeject:保存在消息中心的数据,一般传一个nil
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(sureButtonDidClicked) name:@"SureButtonClickedNotificationName" object:nil];
    //取消按钮我们需要传递一些参数
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(cancelButtonClicked:) name:@"CancelButtonClickedNotificationName" object:nil];
    
}

首先在控制器中添加一个按钮点击事件,然后设置弹窗视图(至于如何自定义弹窗视图,请查看我的上一篇文章),接着我们在这里向消息中心注册消息,为什么在这里注册呢?因为我们是要在控制器中获取到弹窗视图的数据,在控制器中注册相应的消息后,控制器就会监听发出我们注册消息的对象,然后执行相应的方法,所以在控制器中注册消息。

接着我们在自定义弹窗视图的类写发送消息的代码,那么又该在哪里写呢?应该在弹窗视图上的按钮被点击了之后写,所以:


//LSRAlertView.m
- (IBAction)topButonClicked:(UIButton *)sender {
     [self dismiss];
    //这里按钮被点击了,此时需要发出消息
    //name:消息的名称,必须和所监听的消息的名称相同
    //object:需要回调的数据
    //userInfo:也是需要回调的数据
    [[NSNotificationCenter defaultCenter]postNotificationName:@"SureButtonClickedNotificationName" object:nil userInfo:nil];
   
}
- (IBAction)bottomButtonClicked:(UIButton *)sender {
    //发出消息的时候回调参数
    [self dismiss];
    [[NSNotificationCenter defaultCenter]postNotificationName:@"CancelButtonClickedNotificationName" object:@"object" userInfo:@{@"name":@"jack"}];
    
}

发送消息我们用postNotificationName,这里需要注意的是发送消息的名称一定要和之前在控制器中注册的消息名对应起来,另外如果我们需要传递一些数据,就将传递的数据写在 object 或者  userInfo 中,前者是一个字符串类型,后者是一个字典类型。

然后是我们在控制器监听到弹窗视图发出的消息后执行的操作:

//ViewController.m
-(void)sureButtonDidClicked{
    //这里不需要回调参数
    NSLog(@"确定按钮被点击了");
    
    //在这里移除消息
    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"SureButtonClickedNotificationName" object:nil];
} 
-(void)cancelButtonClicked:(NSNotification *)notification{
    //这里将传递过来的参数打印出来
    NSLog(@"%@",notification.object);
    NSLog(@"%@",notification.userInfo);
    
    //同样在这里移除消息
    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"CancelButtonClickedNotificationName" object:nil];
    
}

这里需要注意两点,一是如何取出消息中的数据,我们使用notification的属性object和userInfo来取得相应的数据。第二点也是非常重要的就是一定要将消息中的消息移除,一定要将消息中的消息移除,一定要将消息中的消息移除。如果不移除就会导致点击一次按钮触发多次事件,因为有多个相同的消息同时注册了。

最后是打印的信息:

2016-11-04 15:51:53 sinat_24199205 阅读数 183
  • iOS移动开发从入门到精通(Xcode11 & Swift5)

    【课程特点】 学习iOS开发,请选本套课程,理由如下: 1、180节大容量课程:包含了iOS开发中的大部分实用技能; 2、创新的教学模式:手把手教您iOS开发技术,一看就懂,一学就会; 3、贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标; 4、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间; 【课程内容】 本视频教程拥有180节课程,包含iOS开发的方方面面:iOS开发基础理论知识、 视图、视图控制器、多媒体、数据处理、常用插件、信用卡卡号识别、自动化测试、网络访问、多线程、ShareSDK社会化分享、CoreImage、CoreText、CoreML机器学习、ARKit增强现实、面部检测、Storyboard技巧、关键帧动画、本地通知、陀螺仪相机定位设备、本地化、通过IAP内购实现营利、App上传与审核等超多干货! 

    2571 人正在学习 去看看 李发展

    在实际开发中我们会经常用到通知机制,iOS中的通知中心(NSNotificationCenter)与javascript中的addEventListener相似。

1.通知中心(NSNotificationCenter)实际是在程序内部提供了一种广播机制。把接收到的消息,根据内部的消息转发表,将消息转发给需要的对象。这句话其实已经很明显的告诉我们要如何使用通知了。第一步:在需要的地方注册要观察的通知,第二步:在某地方发送通知。(这里注意:发送的通知可能是我们自定义的,也可能是系统的)。


2. 具体如何使用通知:

比如在某个控制器中需要观察某通知,那么代码如下:


在需要发送通知的地方代码如下:


已经是一目了然了。但是还没结束,千万不要忘了在注册观察通知的控制器的dealloc方法中移除要观察的通知。这是因为,当控制器因为某些原因比如内存问题而被销毁的时候,通知中心被注册的该通知还是存在的,而当其他有地方发送该通知的时候,通知中心会继续转发,但是转发的对象已经不存在了,这时候就会crash了。


这也可以在viewWillAppear和viewWillDisappear方法中配对使用

2018-11-06 16:23:49 lqq200912408 阅读数 596
  • iOS移动开发从入门到精通(Xcode11 & Swift5)

    【课程特点】 学习iOS开发,请选本套课程,理由如下: 1、180节大容量课程:包含了iOS开发中的大部分实用技能; 2、创新的教学模式:手把手教您iOS开发技术,一看就懂,一学就会; 3、贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标; 4、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间; 【课程内容】 本视频教程拥有180节课程,包含iOS开发的方方面面:iOS开发基础理论知识、 视图、视图控制器、多媒体、数据处理、常用插件、信用卡卡号识别、自动化测试、网络访问、多线程、ShareSDK社会化分享、CoreImage、CoreText、CoreML机器学习、ARKit增强现实、面部检测、Storyboard技巧、关键帧动画、本地通知、陀螺仪相机定位设备、本地化、通过IAP内购实现营利、App上传与审核等超多干货! 

    2571 人正在学习 去看看 李发展

通知相关系列文章
iOS10 之前通知使用介绍
[iOS] 通知详解: UIUserNotification
iOS10 相关API
[iOS] 通知详解:iOS 10 UserNotifications API
iOS10 本地/远程通知
[iOS] 通知详解: iOS 10 UserNotifications
iOS10 通知附加包
[iOS] 通知详解: iOS 10 UserNotifications – 附加包Media Attachments
iOS10 自定义UI
[iOS] 通知详解: iOS 10 UserNotifications – 自定义通知UI

新建 Notification content extension

通知UI的自定义使用到了Notification content extension,同创建Notification Service Extension一样,我们需要创建一个新的 Target ,只不过这次选择Notification content extension

下一步,为这个Target起一个名字,完成即可!

可以看到多了下面几个文件:

这里的NotificationViewController就是我们编写自定义UI逻辑的控制器,他和一般的控制器一样,MainInterface.storyboard是与其绑定的,可以在此往storyboard添加控件。Info.plist为其相关的配置文件,有些操作需要在这里配置一些设置后,才能看到预期的效果,下面关于此部分的所有配置,都是在这里进行的。

NotificationViewController中,实现了UNNotificationContentExtension协议,他有两个协议方法

// 必须实现,用来处理自定义UI的内容
public func didReceive(_ notification: UNNotification)
// 选择实现,用来处理action的事件
optional public func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void)

第一个是必须要实现的,在NotificationViewController默认已经实现了,主要是处理当通知来的时候,布局自定义的UI内容以及相关的处理逻辑的地方;
第二个方法,当前发送的通知带有快捷操作action的时候(UNNotificationAction),来处理相关的点击事件。

因为我们自定义的任何View都是无法交互的,只能借助添加的action来处理相关的事件。

绑定 Category

Notification content extension添加完成后,在通知界面是看不到我们自定义的UI的,还需要绑定相关的 Category,即在创建通知的时候,我们添加的UNNotificationCategory,如果没有需要交互的action,可以传个空数组:

let category = UNNotificationCategory(identifier: "categoryidentifier", actions: [], intentIdentifiers: [], options: UNNotificationCategoryOptions.customDismissAction)
        UNUserNotificationCenter.current().setNotificationCategories(Set.init([category]))

然后在该扩展下的Info.plist中添加该Categoryidentifier,对应着UNNotificationExtensionCategory字段:

注意:这里的UNNotificationExtensionCategory可以修改为数组类型,如果我们有多个Category公用一套UI,可以将此值修改为Array类型,然后在数组里添加多个 Category 的identifier。

再去发送通知,注意此时的Payload中要添加category字段:

{
"aps":
    {
        "alert":
        {
            "title":"iOS10远程推送标题",
            "subtitle" : "iOS10 远程推送副标题",
            "body":"这是在iOS10以上版本的推送内容,并且携带来一个图片附件"
        },

"category":"categoryidentifier",
        "badge":1,
        "mutable-content":1,
        "sound":"default",
"image":"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3078873712,1340878922&fm=26&gp=0.jpg"
        
    }
}

弹框和锁屏页显示的内容和之前一样,打开通知或者下拉弹框,就会看到我们自定义的页面了:

比较丑的那部分就是我们自定义的UI了,可以看到真的很丑,大小还不合适,而且和系统默认的也重复的。

如果我们想要隐藏系统默认的内容页面,也就是下面的那部分,头是隐藏不了的;只需要在Info.plist里添加字段UNNotificationExtensionDefaultContentHidden,bool类型并设置其值为YES;

关于页面太大的问题,有的说通过修改其宽高比UNNotificationExtensionInitialContentSizeRatio的值,如果你的UI是固定的,可以通过适配大部分屏幕后,通过修改此值来得到合适的宽高比视图,但其值也是需要各种尝试的。
另外也可以使用autolayout,如果是在storyboard里添加的实图,顺便添加相应的约束即可;然后重新发送消息,大概就是这个样子:

这样,通知页面会先显示一个大的页面,然后再resize到约束后的页面大小,这样就会一个缩放的动画,这是因为在通知即将展示的时候,系统还没有调用我们的约束代码,也就是约束还没有起效,所以会有个resize的动画过渡。
为解决这个问题,只能在自定义UI的时候配合UNNotificationExtensionInitialContentSizeRatio设置合适页面大小,即采用固定的样式来展示通知内容。

显示附加包(attachment)的内容

如果我们的通知是携带附加包的,例如一张图片,添加自定义的UI后,打开通知或者下拉弹框会发现,大图不显示了,我们可以把相关的内容显示到自定义的UI上,还是以图片为例,在didReceive方法里添加以下获取附加包数据的代码:

if let att = notification.request.content.attachments.first {

            if att.url.startAccessingSecurityScopedResource() {
                self.coverImage.image  = UIImage(contentsOfFile: att.url.path)
                att.url.stopAccessingSecurityScopedResource()
            }
        }

这里需要说一下startAccessingSecurityScopedResourcestopAccessingSecurityScopedResource方法:
因为attachment是由系统单独管理的,所以这里我们在使用attachment之前,需要告诉iOS系统,我们需要使用它,并且在使用完毕之后告诉系统我们使用完毕了。对应上述代码就是startAccessingSecurityScopedResource()和stopAccessingSecurityScopedResource()的操作。当我们获取到了attachment的使用权之后,我们就可以使用那个文件获取我们想要的信息了。

再去发送上面的Payload,打开后就是这样了:

意思是那么个意思,但是加载的图片好像不太完整,上面我们是从attachment里面获取的,目前不清楚出现这个情况的原因,可能原数据被压缩了导致数据不全。所以,我们可以从发送的Payload中来获取数据:

if let aps = notification.request.content.userInfo["aps"] as? [String: Any] {

            if let imagePath = aps["image"] as? String {

                if let url = URL(string: imagePath) {

                    if let data = try? Data.init(contentsOf: url) {

                        self.coverImage.image = UIImage(data: data)
                    }
                }
            }
        }

这样就能正常显示了:

处理action事件

如果我们添加的category是带有action的,并且action的点击事件要响应到我们自定义的UI里面,例如点击的时候更换一个图片, 就需要UNNotificationContentExtension协议的另一个协议方法了:

// response:可以拿到点击的action,和通知的内容
// completion:处理完成后需要告诉系统,接下来该如何处理该通知
optional public func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void)

UNNotificationContentExtensionResponseOption 是一个枚举,他有三个值:

@available(iOS 10.0, *)
public enum UNNotificationContentExtensionResponseOption : UInt {

    // 通知页面不会消失,例如更新UI,显示出来
    case doNotDismiss
// 关闭当前通知页面
    case dismiss
// 将此action事件传递给app,在通知中心的代理方法里继续处理该事件
    case dismissAndForwardAction
}

需要注意的是,如果实现了此方法,就需要对所有添加的action进行处理,而不能只处理某个action

例如我们这样处理点击事件:

func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
// 改变标题
        self.label?.text = self.label?.text ?? "" + "点击了 "
        
        if response.actionIdentifier == "okidentifier" {
            // 点击了查看按钮,这里改变了标题的颜色

            self.label?.textColor = UIColor.red
            
            completion(.doNotDismiss)
        } else if response.actionIdentifier == "cancelidentifier" {
            // 点击了关闭,直接关闭通知
            completion(.dismiss)
        } else {
            // 如果还有其他的按钮,交给app处理
            completion(.dismissAndForwardAction)
        }
    }

然后,在创建通知的时候,添加相应的action:

let okAction = UNNotificationAction(identifier: "okidentifier", title: "查看", options: UNNotificationActionOptions.foreground)
   
        let cancel = UNNotificationAction(identifier: "cancelidentifier", title: "关闭", options: UNNotificationActionOptions.destructive)
        
        let category = UNNotificationCategory(identifier: "categoryidentifier", actions: [okAction, cancel], intentIdentifiers: [], options: UNNotificationCategoryOptions.customDismissAction)
        UNUserNotificationCenter.current().setNotificationCategories(Set.init([category]))

再次发生Payload,点击通知的查看action,会发现标题和标题的颜色都修改了。

处理快捷回复(输入文字)

前面知道,我们可以在通知中心进行快捷回复,只需要创建UNTextInputNotificationAction的action,添加到对应的category即可:

let okAction = UNTextInputNotificationAction(identifier: "okidentifier", title: "回复", options: .foreground, textInputButtonTitle: "快捷回复", textInputPlaceholder: "请输入。。。")
        
        
        let cancel = UNNotificationAction(identifier: "cancelidentifier", title: "关闭", options: UNNotificationActionOptions.destructive)
        
        let category = UNNotificationCategory(identifier: "categoryidentifier", actions: [okAction, cancel], intentIdentifiers: [], options: UNNotificationCategoryOptions.customDismissAction)
        UNUserNotificationCenter.current().setNotificationCategories(Set.init([category]))

这里,我们需要这样来处理接收到的反馈:

func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
        self.label?.text = "点击了 "
        
        if response.actionIdentifier == "okidentifier" {
            

            // 这里处理输入框的事件
            if let txRes = response as? UNTextInputNotificationResponse {
                // 如果是输入框的反馈,获取输入内容,显示出来
                let text = txRes.userText
                self.label?.text = text
            }
            
            // 点击了查看按钮,这里改变了标题的颜色
            self.label?.textColor = UIColor.red
            
            completion(.doNotDismiss)
        } else if response.actionIdentifier == "cancelidentifier" {
            // 点击了关闭,直接关闭通知
            completion(.dismiss)
        } else {
            // 如果还有其他的按钮,交给app处理
            completion(.dismissAndForwardAction)
        }
    }

然后在通知中心点击回复按钮的时候会弹出输入框,输入结束后,通知中心即显示了输入的内容:

到此,断断续续,总算是把通知相关的内容整体过了一遍,虽然感觉上还是有些逻辑混乱,基本上能够体现通知的一些使用方法。

参考文章
iOS10-UserNotifications
WWDC2016 Session笔记 - iOS 10 推送Notification新特性

2016-12-16 12:13:23 Aaidong 阅读数 779
  • iOS移动开发从入门到精通(Xcode11 & Swift5)

    【课程特点】 学习iOS开发,请选本套课程,理由如下: 1、180节大容量课程:包含了iOS开发中的大部分实用技能; 2、创新的教学模式:手把手教您iOS开发技术,一看就懂,一学就会; 3、贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标; 4、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间; 【课程内容】 本视频教程拥有180节课程,包含iOS开发的方方面面:iOS开发基础理论知识、 视图、视图控制器、多媒体、数据处理、常用插件、信用卡卡号识别、自动化测试、网络访问、多线程、ShareSDK社会化分享、CoreImage、CoreText、CoreML机器学习、ARKit增强现实、面部检测、Storyboard技巧、关键帧动画、本地通知、陀螺仪相机定位设备、本地化、通过IAP内购实现营利、App上传与审核等超多干货! 

    2571 人正在学习 去看看 李发展

原文:http://www.cnblogs.com/yinxiao-bai1014/p/5949016.html

一、引言

        关于通知,无论与远程Push还是本地通知,以往的iOS系统暴漏给开发者的接口都是十分有限的,开发者只能对标题和内容进行简单的定义,至于UI展示和用户交互行为相关的部分,开发者开发起来都十分困难。至于本地通知,iOS10之前采用的是UILocationNotification类,远程通知有苹果服务器进行转发,本地通知和远程通知其回调的处理都是通过AppDelegate中的几个回调方法来完成。iOS10系统中,通知功能的增强是一大优化之处,iOS10中将通知功能整合成了一个框架UserNotification,其结构十分类似于iOS8中的UIWebView向WebKit框架整合的思路。并且UserNotification相比之前的通知功能更加强大,主要表现在如下几点:

1.通知处理代码可以从AppDelegate中剥离。

2.通知的注册,设置,处理更加结构化,更易于模块化开发。

3.UserNotification支持自定义通知音效和启动图。

4.UserNotification支持向通知内容中添加媒体附件,例如音频,视频。

5.UserNotification支持开发者定义多套通知模板。

6.UserNotification支持完全自定义的通知界面。

7.UserNotification支持自定义通知中的用户交互按钮。

8.通知的触发更加容易管理。

从上面列举的几点就可以看出,iOS10中的UsreNotification真的是一个大的改进,温故而知新,关于iOS之前版本本地通知和远程通知的相关内容请查看如下博客:

本地推送:http://my.oschina.net/u/2340880/blog/405491

远程推送:http://my.oschina.net/u/2340880/blog/413584

二、UserNotification概览

        学习一个新的框架或知识模块时,宏观上了解其体系,大体上掌握其结构是十分必要的,这更有利于我们对这个框架或模块的整体把握与理解。UserNotification框架中拆分定义了许多类、枚举和结构体,其中还定义了许多常量,类与类之间虽然关系复杂,但脉络十分清晰,把握住主线,层层分析,边很容易理解和应用UserNotification框架。

        下图中列举了UserNotification框架中所有核心的类:

如图中关系所示,UserNotification框架中的核心类列举如下:

UNNotificationCenter:通知管理中心,单例,通知的注册,接收通知后的回调处理等,是UserNotification框架的核心。

UNNotification:通知对象,其中封装了通知请求。

UNNotificationSettings:通知相关设置。

UNNotificationCategory:通知模板。

UNNotificationAction:用于定义通知模板中的用户交互行为。

UNNotificationRequest:注册通知请求,其中定义了通知的内容和触发方式。

UNNotificationResponse:接收到通知后的回执。

UNNotificationContent:通知的具体内容。

UNNotificationTrigger:通知的触发器,由其子类具体定义。

UNNotificationAttachment:通知附件类,为通知内容添加媒体附件。

UNNotificationSound:定义通知音效。

UNPushNotificationTrigger:远程通知的触发器,UNNotificationTrigger子类。

UNTimeInervalNotificationTrigger:计时通知的触发器,UNNotificationTrigger子类。

UNCalendarNotificationTrigger:周期通知的触发器,UNNotificationTrigger子类。

UNLocationNotificationTrigger:地域通知的触发器,UNNotificationTrigger子类。

UNNotificationCenterDelegate:协议,其中方法用于监听通知状态。

三、进行通知用户权限申请与创建普通的本地通知

        要在iOS系统中使用通知,必须获取到用户权限,UserNotification框架中申请通知用户权限需要通过UNNotificationCenter来完成,示例如下:

//进行用户权限的申请
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionBadge|UNAuthorizationOptionSound|UNAuthorizationOptionAlert|UNAuthorizationOptionCarPlay completionHandler:^(BOOL granted, NSError * _Nullable error) {
      //在block中会传入布尔值granted,表示用户是否同意
      if (granted) {
            //如果用户权限申请成功,设置通知中心的代理
            [UNUserNotificationCenter currentNotificationCenter].delegate = self;
      }
}];

申请用户权限的方法中需要传入一个权限内容的参数,其枚举定义如下:

typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions) {
    //允许更新app上的通知数字
    UNAuthorizationOptionBadge   = (1 << 0),
    //允许通知声音
    UNAuthorizationOptionSound   = (1 << 1),
    //允许通知弹出警告
    UNAuthorizationOptionAlert   = (1 << 2),
    //允许车载设备接收通知
    UNAuthorizationOptionCarPlay = (1 << 3),
};

获取到用户权限后,使用UserNotification创建普通的通知,示例代码如下:

    //通知内容类
    UNMutableNotificationContent * content = [UNMutableNotificationContent new];
    //设置通知请求发送时 app图标上显示的数字
    content.badge = @2;
    //设置通知的内容
    content.body = @"这是iOS10的新通知内容:普通的iOS通知";
    //默认的通知提示音
    content.sound = [UNNotificationSound defaultSound];
    //设置通知的副标题
    content.subtitle = @"这里是副标题";
    //设置通知的标题
    content.title = @"这里是通知的标题";
    //设置从通知激活app时的launchImage图片
    content.launchImageName = @"lun";
    //设置5S之后执行
    UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
    UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:@"NotificationDefault" content:content trigger:trigger];
    //添加通知请求
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        
    }];

效果如下面图示:

               

四、通知音效类UNNotificationSound

        通知可以进行自定义的音效设置,其中方法如下:

//系统默认的音效
+ (instancetype)defaultSound;
//自定义的音频音效
/*
注意,音频文件必须在bundle中或者在Library/Sounds目录下
*/
+ (instancetype)soundNamed:(NSString *)name __WATCHOS_PROHIBITED;

五、通知触发器UNNotificationTrigger

        通知触发器可以理解为定义通知的发送时间,UNNotificationTrigger是触发器的基类,具体的触发器由它的四个子类实现,实际上,开发者在代码中可能会用到的触发器只有三种,UNPushNotificationTrigger远程推送触发器开发者不需要创建使用,远程通知有远程服务器触发,开发者只需要创建与本地通知有关的触发器进行使用。

1.UNTimeIntervalNotificationTrigger

        UNTimeIntervalNotificationTrigger是计时触发器,开发者可以设置其在添加通知请求后一定时间发送。

//创建触发器 在timeInterval秒后触发 可以设置是否循环触发
+ (instancetype)triggerWithTimeInterval:(NSTimeInterval)timeInterval repeats:(BOOL)repeats;
//获取下次触发的时间点
- (nullable NSDate *)nextTriggerDate;

2.UNCalendarNotificationTrigger

        UNCalendarNotificationTrigger是日历触发器,开发者可以设置其在某个时间点触发。

//创建触发器 设置触发时间 可以设置是否循环触发
+ (instancetype)triggerWithDateMatchingComponents:(NSDateComponents *)dateComponents repeats:(BOOL)repeats;
//下一次触发的时间点
- (nullable NSDate *)nextTriggerDate;

3.UNLocationNotificationTrigger

        UNLocationNotificationTrigger是地域触发器,开发者可以设置当用户进入某一区域时触发。

//地域信息
@property (NS_NONATOMIC_IOSONLY, readonly, copy) CLRegion *region;
//创建触发器
+ (instancetype)triggerWithRegion:(CLRegion *)region repeats:(BOOL)repeats __WATCHOS_PROHIBITED;

六、为通知内容添加附件

        附件主要指的是媒体附件,例如图片,音频和视频,为通知内容添加附件需要使用UNNotificationAttachment类。示例代码如下:

    //创建图片附件
    UNNotificationAttachment * attach = [UNNotificationAttachment attachmentWithIdentifier:@"imageAttach" URL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"2" ofType:@"jpg"]] options:nil error:nil];
    UNMutableNotificationContent * content = [UNMutableNotificationContent new];
    //设置附件数组
    content.attachments = @[attach];
    content.badge = @1;
    content.body = @"这是iOS10的新通知内容:普通的iOS通知";
    //默认的通知提示音
    content.sound = [UNNotificationSound defaultSound];
    content.subtitle = @"这里是副标题";
    content.title = @"这里是通知的标题";
    //设置5S之后执行
    UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
    UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:@"NotificationDefaultImage" content:content trigger:trigger];
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        
    }];

效果如下图:

                 

需要注意,UNNotificationContent的附件数组虽然是一个数组,但是系统的通知模板只能展示其中的第一个附件,设置多个附件也不会有额外的效果,但是如果开发者进行通知模板UI的自定义,则此数组就可以派上用场了。音频附件界面如下:

需要注意,添加附件的格式和大小都有一定的要求,如下表格所示:

创建通知内容附件UNNotificationAttachment实例的方法中有一个options配置字典,这个字典中可以进行配置的键值对如下:

//配置附件的类型的键 需要设置为NSString类型的值,如果不设置 则默认从扩展名中推断
extern NSString * const UNNotificationAttachmentOptionsTypeHintKey __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
//配置是否隐藏缩略图的键 需要配置为NSNumber 0或者1
extern NSString * const UNNotificationAttachmentOptionsThumbnailHiddenKey __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
//配置使用一个标准的矩形来对缩略图进行裁剪,需要配置为CGRectCreateDictionaryRepresentation(CGRect)创建的矩形引用
extern NSString * const UNNotificationAttachmentOptionsThumbnailClippingRectKey __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
//使用视频中的某一帧作为缩略图 配置为NSNumber时间
extern NSString * const UNNotificationAttachmentOptionsThumbnailTimeKey __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);

七、定义通知模板UNNotificationCategory

        聊天类软件在iOS系统中,常常采用后台推送的方式推送新消息,用户可以在不进入应用程序的情况下,直接在左面回复通知推送过来的信息,这种功能就是通过UNNotificationCategory模板与UNNotificationAction用户活动来实现的。关于文本回复框,UserNotification框架中提供了UNTextInputNotificationAction类,其是UNNotificationAction的子类。示例代码如下:

    //创建用户活动
    /*
    options参数可选如下:
    //需要在解开锁屏下使用
    UNNotificationActionOptionAuthenticationRequired
    //是否指示有破坏性
    UNNotificationActionOptionDestructive
    //是否允许活动在后台启动app
    UNNotificationActionOptionForeground
    //无设置
    UNNotificationActionOptionNone
    */
    UNTextInputNotificationAction * action = [UNTextInputNotificationAction actionWithIdentifier:@"action" title:@"回复" options:UNNotificationActionOptionAuthenticationRequired textInputButtonTitle:@"活动" textInputPlaceholder:@"请输入回复内容"];
    //创建通知模板
    UNNotificationCategory * category = [UNNotificationCategory categoryWithIdentifier:@"myNotificationCategoryText" actions:@[action] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    UNMutableNotificationContent * content = [UNMutableNotificationContent new];
    content.badge = @1;
    content.body = @"这是iOS10的新通知内容:普通的iOS通知";
    //默认的通知提示音
    content.sound = [UNNotificationSound defaultSound];
    content.subtitle = @"这里是副标题";
    content.title = @"这里是通知的标题";
    //设置通知内容对应的模板 需要注意 这里的值要与对应模板id一致
    content.categoryIdentifier = @"myNotificationCategoryText";
    //设置5S之后执行
    UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
      [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:category, nil]];
    UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:@"NotificationDefaultText" content:content trigger:trigger];
  
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        
    }];

需要注意,要使用模板,通知内容UNNotificationContent的categoryIdentifier要与UNNotificationCategory的id一致。效果如下:

        也可以为通知模板添加多个自定义的用户交互按钮,示例如下:

UNNotificationAction * action = [UNNotificationAction actionWithIdentifier:@"action" title:@"活动标题1" options:UNNotificationActionOptionNone];
    UNNotificationAction * action2 = [UNNotificationAction actionWithIdentifier:@"action" title:@"活动标题2" options:UNNotificationActionOptionNone];
    UNNotificationAction * action3 = [UNNotificationAction actionWithIdentifier:@"action" title:@"活动标题3" options:UNNotificationActionOptionNone];
    UNNotificationAction * action4 = [UNNotificationAction actionWithIdentifier:@"action" title:@"活动标题4" options:UNNotificationActionOptionNone];
     UNNotificationCategory * category = [UNNotificationCategory categoryWithIdentifier:@"myNotificationCategoryBtn" actions:@[action,action2,action3,action4] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    UNMutableNotificationContent * content = [UNMutableNotificationContent new];
    content.badge = @1;
    content.body = @"这是iOS10的新通知内容:普通的iOS通知";
    //默认的通知提示音
    content.sound = [UNNotificationSound defaultSound];
    content.subtitle = @"这里是副标题";
    content.title = @"这里是通知的标题";
    content.categoryIdentifier = @"myNotificationCategoryBtn";
    //设置5S之后执行
    UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
    UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:@"NotificationDefault" content:content trigger:trigger];
    [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:category, nil]];
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        
    }];

需要注意,系统模板最多支持添加4个用户交互按钮,如下图:

八、自定义通知模板UI

        通过前边的介绍,我们发现通过UserNotification框架开发者已经可以完成许多从来很难实现的效果。然而这都不是UserNotification框架最强大的地方,UserNotification框架最强大的地方在于其可以完全自定义通知的UI界面。

        完全自定义通知界面是通过iOS扩展来实现的,首先创建一个新的target,如下图:

选择Notification Content,如下:

创建完成后,会发现工程中多了一个Notification Content的扩展,其中自带一个storyboard文件和一个NotificationViewController类,开发者可以在storyboard文件或者直接在Controller类中进行自定义界面的编写。

    需要注意,NotificationViewController自动遵守了UNNotificationContentExtension协议,这个协议专门用来处理自定义通知UI的内容展示,其中方法列举如下:

//接收到通知时会被调用
/*
开发者可以从notification对象中拿到附件等内容进行UI刷新
*/
- (void)didReceiveNotification:(UNNotification *)notification;
//当用户点击了通知中的用户交互按钮时会被调用
/*
response对象中有通知内容相关信息
在回调block块completion中,开发者可以传入一个UNNotificationContentExtensionResponseOption参数来告诉系统如何处理这次用户活动
UNNotificationContentExtensionResponseOption枚举中可选值如下:
typedef NS_ENUM(NSUInteger, UNNotificationContentExtensionResponseOption) {
    //不关闭当前通知界面
    UNNotificationContentExtensionResponseOptionDoNotDismiss,
    //关闭当前通知界面
    UNNotificationContentExtensionResponseOptionDismiss,
    //关闭当前通知界面并将用户活动传递给宿主app处理
    UNNotificationContentExtensionResponseOptionDismissAndForwardAction,
} __IOS_AVAILABLE(10_0) __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __OSX_UNAVAILABLE;
*/
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption option))completion;
/*
这个属性作为get方法进行实现 这个方法用来返回一个通知界面要显示的媒体按钮
typedef NS_ENUM(NSUInteger, UNNotificationContentExtensionMediaPlayPauseButtonType) {
    //不显示媒体按钮
    UNNotificationContentExtensionMediaPlayPauseButtonTypeNone,
    //默认的媒体按钮 当点击按钮后 进行播放与暂停的切换 按钮始终显示
    UNNotificationContentExtensionMediaPlayPauseButtonTypeDefault,
    //Overlay风格 当点击按钮后,媒体播放,按钮隐藏 点击媒体后,播放暂停,按钮显示。
    UNNotificationContentExtensionMediaPlayPauseButtonTypeOverlay,
} __IOS_AVAILABLE(10_0) __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __OSX_UNAVAILABLE;
*/
@property (nonatomic, readonly, assign) UNNotificationContentExtensionMediaPlayPauseButtonType mediaPlayPauseButtonType;
//返回媒体按钮的位置
@property (nonatomic, readonly, assign) CGRect mediaPlayPauseButtonFrame;
//返回媒体按钮的颜色
@property (nonatomic, readonly, copy) UIColor *mediaPlayPauseButtonTintColor;
//点击播放按钮的回调
- (void)mediaPlay;
//点击暂停按钮的回调
- (void)mediaPause;
//媒体开始播放的回调
- (void)mediaPlayingStarted __IOS_AVAILABLE(10_0) __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __OSX_UNAVAILABLE;
//媒体开始暂停的回调
- (void)mediaPlayingPaused __IOS_AVAILABLE(10_0) __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __OSX_UNAVAILABLE;

需要注意,自定义的通知界面上虽然可以放按钮,可以放任何UI控件,但是其不能进行用户交互,唯一可以进行用户交互的方式是通过协议中的媒体按钮及其回调方法。

        定义好了通知UI模板,若要进行使用,还需要再Notification Content扩展中的info.plist文件的NSExtension字典的NSExtensionAttributes字典里进行一些配置,正常情况下,开发者需要进行配置的键有3个,分别如下:

UNNotificationExtensionCategory:设置模板的categoryId,用于与UNNotificationContent对应。

UNNotificationExtensionInitialContentSizeRatio:设置自定义通知界面的高度与宽度的比,宽度为固定宽度,在不同设备上有差别,开发者需要根据宽度计算出高度进行设置,系统根据这个比值来计算通知界面的高度。

UNNotificationExtensionDefaultContentHidden:是有隐藏系统默认的通知界面。

配置info.plist文件如下:

用如下的代码创建通知:

UNNotificationAction * action = [UNNotificationAction actionWithIdentifier:@"action" title:@"活动标题1" options:UNNotificationActionOptionNone];
    //根据id拿到自定义UI的模板
    UNNotificationCategory * category = [UNNotificationCategory categoryWithIdentifier:@"myNotificationCategoryH" actions:@[action] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    UNMutableNotificationContent * content = [UNMutableNotificationContent new];
    content.badge = @1;
    content.body = @"这是iOS10的新通知内容:普通的iOS通知";
    //默认的通知提示音
    content.sound = [UNNotificationSound defaultSound];
    content.subtitle = @"这里是副标题";
    content.title = @"这里是通知的标题";
    content.categoryIdentifier = @"myNotificationCategoryH";
    //设置5S之后执行
    UNTimeIntervalNotificationTrigger * trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
    UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:@"NotificationDefaultCustomUIH" content:content trigger:trigger];
    [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:category, nil]];
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        
    }];

效果如下图:

如果将UNNotificationExtensionDefaultContentHidden键值设置为0或者不设置,则不会隐藏系统默认的UI,如下:

九、通知回调的处理

        UserNotification框架对于通知的回调处理,是通过UNUserNotificationCenterDelegate协议来实现的,这个协议中有两个方法,如下:

/*
这个方法在应用在前台,并且将要弹出通知时被调用,后台状态下弹通知不会调用这个方法
这个方法中的block块completionHandler()可以传入一个UNNotificationPresentationOptions类型的枚举
有个这个参数,开发者可以设置在前台状态下,依然可以弹出通知消息,枚举如下:
typedef NS_OPTIONS(NSUInteger, UNNotificationPresentationOptions) {
    //只修改app图标的消息数
    UNNotificationPresentationOptionBadge   = (1 << 0),
    //只提示通知音效
    UNNotificationPresentationOptionSound   = (1 << 1),
    //只弹出通知框
    UNNotificationPresentationOptionAlert   = (1 << 2),
} __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
//什么都不做
static const UNNotificationPresentationOptions UNNotificationPresentationOptionNone 
*/
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
/*
这个方法当接收到通知后,用户点击通知激活app时被调用,无论前台还是后台
*/
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;

十、UserNotification框架中其他零散知识

        前面所介绍的内容基本涵盖了UserNotification框架中所有的内容,在以后的应用开发中,开发者可以在通知方面发挥更大的想象力与创造力,给用户更加友好的体验。除了前边所介绍过的核心内容外,UserNotification框架中还有一些零散的类、枚举等。

1.错误码描述

typedef NS_ENUM(NSInteger, UNErrorCode) {
    //通知不被允许
    UNErrorCodeNotificationsNotAllowed = 1,
    
    //附件无效url
    UNErrorCodeAttachmentInvalidURL = 100,
    //附件类型错误
    UNErrorCodeAttachmentUnrecognizedType,
    //附件大小错误
    UNErrorCodeAttachmentInvalidFileSize,
    //附件数据错误
    UNErrorCodeAttachmentNotInDataStore,
    UNErrorCodeAttachmentMoveIntoDataStoreFailed,
    UNErrorCodeAttachmentCorrupt,
    
    //时间无效
    UNErrorCodeNotificationInvalidNoDate = 1400,
    //无内容
    UNErrorCodeNotificationInvalidNoContent,
} __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);

2.UNNotification类

@interface UNNotification : NSObject <NSCopying, NSSecureCoding>
//触发的时间
@property (nonatomic, readonly, copy) NSDate *date;
//内置的通知请求对象
@property (nonatomic, readonly, copy) UNNotificationRequest *request;

- (instancetype)init NS_UNAVAILABLE;

@end

3.UNNotificationSettings类

        UNNotificationSettings类主要用来获取与通知相关的信息。

@interface UNNotificationSettings : NSObject <NSCopying, NSSecureCoding>
//用户权限状态
@property (NS_NONATOMIC_IOSONLY, readonly) UNAuthorizationStatus authorizationStatus;
//音效设置
@property (NS_NONATOMIC_IOSONLY, readonly) UNNotificationSetting soundSetting __TVOS_PROHIBITED;
//图标提醒设置
@property (NS_NONATOMIC_IOSONLY, readonly) UNNotificationSetting badgeSetting __WATCHOS_PROHIBITED;
//提醒框设置
@property (NS_NONATOMIC_IOSONLY, readonly) UNNotificationSetting alertSetting __TVOS_PROHIBITED;
//通知中心设置
@property (NS_NONATOMIC_IOSONLY, readonly) UNNotificationSetting notificationCenterSetting __TVOS_PROHIBITED;
//锁屏设置
@property (NS_NONATOMIC_IOSONLY, readonly) UNNotificationSetting lockScreenSetting __TVOS_PROHIBITED __WATCHOS_PROHIBITED;
//车载设备设置
@property (NS_NONATOMIC_IOSONLY, readonly) UNNotificationSetting carPlaySetting __TVOS_PROHIBITED __WATCHOS_PROHIBITED;
//提醒框风格
@property (NS_NONATOMIC_IOSONLY, readonly) UNAlertStyle alertStyle __TVOS_PROHIBITED __WATCHOS_PROHIBITED;

@end

UNNotificationSetting枚举如下:

typedef NS_ENUM(NSInteger, UNNotificationSetting) {
    //不支持
    UNNotificationSettingNotSupported  = 0,
    
    //不可用
    UNNotificationSettingDisabled,
    
    //可用
    UNNotificationSettingEnabled,
} 

UNAuthorizationStatus枚举如下:

typedef NS_ENUM(NSInteger, UNAuthorizationStatus) {
    //为做选择
    UNAuthorizationStatusNotDetermined = 0,
    
    // 用户拒绝
    UNAuthorizationStatusDenied,
    
    // 用户允许
    UNAuthorizationStatusAuthorized
}

UNAlertStyle枚举如下:

typedef NS_ENUM(NSInteger, UNAlertStyle) {
    //无
    UNAlertStyleNone = 0,
    //顶部Banner样式
    UNAlertStyleBanner,
    //警告框样式
    UNAlertStyleAlert,
}

2015-12-04 12:48:07 WKFfantasy 阅读数 262
  • iOS移动开发从入门到精通(Xcode11 & Swift5)

    【课程特点】 学习iOS开发,请选本套课程,理由如下: 1、180节大容量课程:包含了iOS开发中的大部分实用技能; 2、创新的教学模式:手把手教您iOS开发技术,一看就懂,一学就会; 3、贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标; 4、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间; 【课程内容】 本视频教程拥有180节课程,包含iOS开发的方方面面:iOS开发基础理论知识、 视图、视图控制器、多媒体、数据处理、常用插件、信用卡卡号识别、自动化测试、网络访问、多线程、ShareSDK社会化分享、CoreImage、CoreText、CoreML机器学习、ARKit增强现实、面部检测、Storyboard技巧、关键帧动画、本地通知、陀螺仪相机定位设备、本地化、通过IAP内购实现营利、App上传与审核等超多干货! 

    2571 人正在学习 去看看 李发展

首先 我们需要明确的是  NSNotificationCenter的这个类的对象 发送NSNotification的对象

NSNotification的这个对象有三个属性

   name     : 通知的名称,

   object   : 发出的通知的那个对象

   userInfo : 传递的参数,这个参数是字典,通知之间只能以字典的方式传递数据

创建一个通知,这个通知三个参数就是通知的属性

NSMutableDictionary * dict = [NSMutableDictionary dictionary];

dict[@"1"]=@"2";

dict[@"3"]=@"4";

NSNotification * noti = [[NSNotification alloc]initWithName:@"nicai" object:nil userInfo:dict];

不可以这样 因为 这三个参数 属性是readonly 是只读属性。只有get方法,没有set方法

NSNotification * noti1 = [[NSNotification alloc]init];

noti1.name = @"nicai";

noti1.object = nil;

noti1.userInfo = nil;


首先  通知中心 是单例  这个类方法提供快速创建通知中心的对象

NSNotificationCenter * center1 = [NSNotificationCenter defaultCenter];

NSNotificationCenter * center2 = [NSNotificationCenter defaultCenter];

NSLog(@"%@ %@",center1,center2);

两个是一模一样的

  

添加监听者 当通知中心发出通知时,oberver 会根据发出通知的对象object    通知的name 来决定是不是执行selector

两者都一样 就执行。

object若是空的话,name不为空 意味着 不管谁发出name的通知,这个监听者都会接收到通知并执行selector方法

name是空的话  object不为空 只要这个object发出通知,他都会执行相应的selector的方法

[center1 addObserver:self selector:@selector(noti:) name:@"nicai" object:nil];


第一种方式 发出通知 noti是一个NSNotification类型

[center1 postNotification:noti];

  

第二种方式 发出通知,name是通知的名字,object是发出通知的对象

object若是空的话,只要有监听者收到name的通知,他们都会执行相应的selector的方法 无论是谁发出的

[center1 postNotificationName:@"nicai" object:self];

  

第三种方式 发出通知 name是通知的名字  object是发出通知的对象 userInfo是通知要传递的参数

[center1 postNotificationName:@"nicai" object:nil userInfo:nil];



-(void)noti:(NSNotification *)noti{

  

  NSLog(@"传递过来的参数 %@",noti.userInfo);

  NSLog(@"noti %@",noti);

  

}


在控制器销毁的时候 要移除观察者

-(void)dealloc{

  

  NSNotificationCenter * center1 = [NSNotificationCenter defaultCenter];

  

  移除观察者 在这个观察者所有的name 都会移除,

  [center1 removeObserver:self];

  

  移除观察者观察的对应通知,

  [center1 removeObserver:self name:nil object:nil];

  

}



      接收通知失败的原因

   

   ,先发通知,在添加观察者

   有一些对通知理解不深的人,会犯这个错误,如以下写法 应该是先添加观察者,在发通知

   [center1 postNotificationName:@"nicai" object:nil userInfo:nil];

   [center1 addObserver:self selector:@selector(noti:) name:@"nicai" object:nil];

   

   

   二,name不对,

   一些不认真的人,有时候name少拼或者多拼 等等原因吧,让name不一样,那接收通知的肯定不会去执行相应的方法

   [center1 addObserver:self selector:@selector(noti:) name:@"nicaia" object:nil];

   [center1 postNotificationName:@"nicai" object:nil userInfo:nil];

   

   三,object不对,

   可能是程序的习惯吧,我们喜欢在发出通知 或者在接收通知的时候 object都写成self

   这个self如果你细心的话,在两个类中,一个添加观察者,一个发出通知,你会发现self地址是不一样的。

   一般的话,我们在两个不相干的类里面都会把两个object设置为nil 

   除非在同一个控制器里面 我们可以设置为self

   

   [center1 addObserver:self selector:@selector(noti:) name:@"nicaia" object:nil];

   [center1 postNotificationName:@"nicai" object:nil userInfo:nil];

   

   四,没有注册通知

   我记得在iOS8 之下,要在AppDelegate里面要去注册通知

   //注册本地通知

   if (iOS8) { // ios8才需要注册通知

   UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];

   [application registerUserNotificationSettings:setting];

   }

   

   鉴于我对于通知的理解,我给大家提点我的看法

   在一个项目里面,你的通知的名字,用一个专门的.h文件来记录,并且每一个name都要自释义,就是别人一拿到你的name 就知道你要干嘛,另外,在.h里面 如果通知的name你自释义感觉不靠谱的话,尽量用语言来描述

   对于传值的话,如果两个类没有多大联系,你可以用通知来传递,如果有关系,比如a pushb 或者b pop 这些传值是很方便的顺传直接赋值,回传用代码块更方便。另外,用通知传递参数的比较少,可能主要原因是通知的参数不是太容易看出来吧。所以,我们传值能少用通知,就少用通知吧





iOS通知的使用

阅读数 280

iOS通知

博文 来自: u012121216

iOS 通知机制

阅读数 624

iOS通知机制

博文 来自: guoyule2010
没有更多推荐了,返回首页