MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Objective-C中的User Notifications用户通知框架

2022-12-062.3k 阅读

1. 简介

在iOS开发中,User Notifications用户通知框架是向用户传达信息的重要途径。Objective - C作为iOS开发的传统编程语言,对该框架有着全面且深入的支持。用户通知允许应用在适当的时候向用户发送提醒、消息等,这些通知可以以多种形式呈现,如横幅、弹窗、声音,还能在设备锁定屏幕上显示。通过User Notifications框架,开发者能够创建、管理和处理本地以及远程通知,极大地提高应用与用户的交互性。

2. 本地通知

2.1 创建本地通知

要创建本地通知,首先需要引入UserNotifications框架。在Objective - C中,通过UNMutableNotificationContent类来设置通知的内容,如标题、副标题、正文、附件等。以下是一个简单的示例:

#import <UserNotifications/UserNotifications.h>

// 创建通知内容
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:@"新消息" arguments:nil];
content.subtitle = [NSString localizedUserNotificationStringForKey:@"来自好友的消息" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"嗨,最近怎么样?" arguments:nil];
content.sound = [UNNotificationSound defaultSound];

在上述代码中,我们创建了一个UNMutableNotificationContent对象,并设置了标题、副标题、正文以及声音。localizedUserNotificationStringForKey:arguments:方法用于支持本地化,这样应用可以根据用户设备的语言设置来显示相应语言的通知内容。

2.2 设置通知触发时间

通知触发时间决定了何时显示通知。可以使用UNTimeIntervalNotificationTrigger设置基于时间间隔的触发,或者UNCalendarNotificationTrigger基于日历事件的触发。以下是基于时间间隔触发的示例:

// 设置5秒后触发通知
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];

这里创建了一个5秒后触发的通知触发对象,repeats:NO表示该通知只触发一次。如果设置为YES,则会按照指定的时间间隔重复触发。

2.3 调度本地通知

创建好通知内容和触发条件后,需要将通知添加到通知中心进行调度。这通过UNUserNotificationCenter类来实现:

// 创建通知请求
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"localNotification" content:content trigger:trigger];

// 获取通知中心实例
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

// 将通知请求添加到通知中心
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
    if (error) {
        NSLog(@"添加通知请求失败: %@", error);
    }
}];

在这段代码中,我们首先使用通知内容和触发条件创建了一个UNNotificationRequest对象,并为其指定了一个唯一的标识符localNotification。然后获取UNUserNotificationCenter的当前实例,并通过addNotificationRequest:withCompletionHandler:方法将通知请求添加到通知中心。如果添加过程中出现错误,会在完成处理程序中进行日志记录。

3. 远程通知

3.1 注册远程通知

要接收远程通知,应用需要向系统注册远程通知。在AppDelegateapplication:didFinishLaunchingWithOptions:方法中进行如下操作:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 注册远程通知
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;

    UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge;

    [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            });
        } else if (error) {
            NSLog(@"请求授权失败: %@", error);
        }
    }];

    return YES;
}

首先获取UNUserNotificationCenter实例并设置代理,然后定义授权选项,包括提醒、声音和应用图标徽章。通过requestAuthorizationWithOptions:completionHandler:方法向用户请求授权。如果授权成功,在主线程中调用registerForRemoteNotifications方法注册远程通知。

3.2 处理远程通知

当应用收到远程通知时,会调用UNUserNotificationCenterDelegate协议中的方法。在AppDelegate中实现该协议方法来处理通知:

// 应用处于前台时收到通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    UNNotificationContent *content = notification.request.content;
    NSLog(@"收到远程通知: %@", content.body);
    completionHandler(UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound + UNNotificationPresentationOptionBadge);
}

// 应用从后台被激活时收到通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    UNNotificationContent *content = response.notification.request.content;
    NSLog(@"从后台激活收到远程通知: %@", content.body);
    completionHandler();
}

willPresentNotification:withCompletionHandler:方法在应用处于前台时收到通知被调用,开发者可以在此方法中决定如何呈现通知,通过完成处理程序设置呈现选项。didReceiveNotificationResponse:withCompletionHandler:方法在应用从后台被激活时收到通知被调用,开发者可以在此处理通知相关的业务逻辑。

4. 通知内容扩展

4.1 创建通知内容扩展

通知内容扩展允许开发者自定义通知的显示内容,提供更丰富的用户体验。首先在Xcode中创建一个新的Notification Content Extension目标。

在扩展的NotificationViewController中,可以自定义通知的界面。例如,添加一个图片视图来显示图片附件:

#import "NotificationViewController.h"
#import <UserNotificationsUI/UserNotificationsUI.h>

@interface NotificationViewController () <UNNotificationContentExtension>

@property (nonatomic, weak) IBOutlet UIImageView *imageView;

@end

@implementation NotificationViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 配置视图
}

- (void)didReceiveNotification:(UNNotification *)notification {
    UNNotificationAttachment *attachment = notification.request.content.attachments.firstObject;
    if (attachment && [attachment isKindOfClass:[UNNotificationAttachment class]]) {
        NSURL *attachmentURL = attachment.URL;
        NSData *data = [NSData dataWithContentsOfURL:attachmentURL];
        UIImage *image = [UIImage imageWithData:data];
        self.imageView.image = image;
    }
}

@end

在上述代码中,我们在NotificationViewController中实现了UNNotificationContentExtension协议。在didReceiveNotification:方法中,获取通知的附件,如果是图片附件,则将其显示在UIImageView中。

4.2 配置通知内容扩展

要使用通知内容扩展,需要在主应用的Info.plist文件中进行配置。添加一个NSExtension字典,并设置NSExtensionPointIdentifiercom.apple.usernotifications.content-extension。同时,在扩展的Info.plist文件中设置UNNotificationExtensionCategory,指定扩展支持的通知类型。

5. 通知交互

5.1 创建通知操作

通知操作允许用户与通知进行交互,如点击按钮、回复消息等。可以通过UNNotificationAction类来创建操作。以下是创建一个简单的“查看详情”操作的示例:

// 创建“查看详情”操作
UNNotificationAction *viewAction = [UNNotificationAction actionWithIdentifier:@"viewAction" title:@"查看详情" options:UNNotificationActionOptionForeground];

这里创建了一个标识符为viewAction,标题为“查看详情”的操作,UNNotificationActionOptionForeground选项表示点击该操作时会将应用切换到前台。

5.2 创建通知类别

通知类别用于将相关的操作组合在一起。通过UNNotificationCategory类来创建类别:

// 创建通知类别
UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"messageCategory" actions:@[viewAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];

这里创建了一个标识符为messageCategory的通知类别,并将之前创建的“查看详情”操作添加到该类别中。

5.3 注册通知类别

创建好通知类别后,需要将其注册到通知中心:

// 获取通知中心实例
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

// 注册通知类别
[center setNotificationCategories:[NSSet setWithObject:category]];

通过上述代码,将通知类别注册到通知中心,这样在显示通知时,就会根据类别显示相应的操作按钮。

6. 通知的本地化

6.1 字符串本地化

在创建通知内容时,如标题、正文等,可以使用本地化字符串。在项目的Localizable.strings文件中,为不同语言添加对应的字符串。例如,在英文的Localizable.strings文件中添加:

"新消息" = "New Message";
"来自好友的消息" = "Message from friend";
"嗨,最近怎么样?" = "Hi, how are you?";

在中文的Localizable.strings文件中添加:

"新消息" = "新消息";
"来自好友的消息" = "来自好友的消息";
"嗨,最近怎么样?" = "嗨,最近怎么样?";

在代码中使用localizedUserNotificationStringForKey:arguments:方法来加载本地化字符串,如前面创建本地通知内容时的示例。

6.2 日期和时间本地化

如果通知内容中包含日期和时间,也需要进行本地化。可以使用NSDateFormatter类来实现:

NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterShortStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setLocale:[NSLocale currentLocale]];
NSString *localizedDateString = [formatter stringFromDate:date];

上述代码创建了一个NSDateFormatter对象,并根据当前设备的语言和地区设置格式化日期和时间,从而实现日期和时间的本地化显示。

7. 通知的最佳实践

7.1 合理使用通知频率

过度发送通知会导致用户反感,降低用户对应用的好感度。因此,开发者需要根据应用的业务场景,合理控制通知的发送频率。例如,对于即时通讯应用,可以在用户有新消息时发送通知,但如果短时间内有多条消息,可以合并为一条通知,避免频繁打扰用户。

7.2 提供通知设置选项

在应用中,应该提供通知设置选项,允许用户根据自己的需求调整通知的显示方式、声音、是否接收通知等。这样可以提高用户的自主性,让用户更好地掌控应用的通知行为。

7.3 测试通知功能

在开发过程中,要充分测试通知功能,包括本地通知和远程通知。测试不同场景下通知的显示、触发时间、交互操作等是否正常。可以使用模拟器和真机进行测试,确保通知在各种设备和系统版本上都能正常工作。

通过深入理解和合理运用Objective - C中的User Notifications用户通知框架,开发者能够为用户提供更加个性化、及时且友好的通知体验,从而提升应用的整体质量和用户满意度。无论是简单的本地提醒,还是复杂的远程通知交互,该框架都提供了丰富的功能和灵活的配置选项,满足各种应用场景的需求。