# iOS 10 Notifications, Part 1: Requests, Triggers, and Attachments

Language: en
Canonical: [iOS 10 Notifications, Part 1: Requests, Triggers, and Attachments](<https://allluckly.cn/en/journal/2016-09-28-ios-10-notifications-part-1-requests-triggers-and-attachments/>)
中文：[中文 HTML](<https://allluckly.cn/%E6%8A%95%E7%A8%BF/tougao63>)
English: [English HTML](<https://allluckly.cn/en/journal/2016-09-28-ios-10-notifications-part-1-requests-triggers-and-attachments/>)
Published: 2016-09-28T00:00:00+08:00
Modified: 2026-10-23T10:34:15+08:00
Author: 徐不同

Uses local notifications to explain the relationship between UNNotificationRequest, triggers, and the notification center. It manages additions, updates, and deletions through identifiers and introduces valid file paths and configuration for notification attachments.

Originally credited to 徐不同; edited and archived by Bison.

[Source listed in the original](<http://www.jianshu.com/p/3d602a60ca4f>)

English translation of the [Chinese original](<https://allluckly.cn/%E6%8A%95%E7%A8%BF/tougao63>), translated on 2026-10-23. The article body uses automated translation; app descriptions, historical reading notes and video subtitles receive separate editorial checks. Original publication dates, attribution, code and version notes are retained.

**Before you read** This technical note dates from 2015–2017. The examples have not been rerun as part of this archive update. The article covers the UserNotifications APIs in iOS 10.

> This is a long and sometimes difficult article, but consider bookmarking it for when you need the information. If you have the patience, read through it now too.

Starting with this article, I will explain all the notification classes in Apple's newly released iOS10.

Editor: [Bison](<https://allluckly.cn/en/>)  
 Source: [徐不同](<http://www.jianshu.com/p/3d602a60ca4f>)

## 1. A detailed local-notification example

Remember, local notifications also require registering the notification center in appdelegate. Whether the notification switch is enabled is not important here, since this is a local notification, but Apple combines the notification-receipt and notification-tap delegates. Write these 2 methods in appdelegate, and do not forget to register in

```
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
```

registering the notification center. If you use JPush, please refer to the introductory article. Thank you for following along.

Create a UNNotificationRequest instance and assign an identifier. This distinguishes the notification when finding, updating, or deleting it later. Add the request to UNUserNotificationCenter, configure a trigger, and wait for it to fire. A new request with the same identifier but different content updates the earlier notification. To create a local notification, first create a UNNotificationRequest and add it to UNUserNotificationCenter. Here is the code:

```
// 1.创建一个UNNotificationRequest
NSString *requestIdentifer = @"TestRequest";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifer content:content trigger:trigger];

// 2.将UNNotificationRequest类，添加进当前通知中心中
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {

}];
```

Apple's explanation of UNNotificationRequest says a request can notify the user at a scheduled time or location; see UNNotificationTrigger for trigger types. Calling this method replaces a notification request with the same identifier when the notification fires. The system also limits the number of notifications.

That translation may be awkward. Simply put, assign an identifier to UNNotificationRequest so you can add, delete, update, and otherwise manage that notification through it.

Here is the complete notification-creation code:

```
	    // 1.创建通知内容
	    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
	    content.title = @"徐不同测试通知";
	    content.subtitle = @"测试通知";
	    content.body = @"来自徐不同的简书";
	    content.badge = @1;
	    NSError *error = nil;
	    NSString *path = [[NSBundle mainBundle] pathForResource:@"icon_certification_status1@2x" ofType:@"png"];
	    // 2.设置通知附件内容
	    UNNotificationAttachment *att = [UNNotificationAttachment attachmentWithIdentifier:@"att1" URL:[NSURL fileURLWithPath:path] options:nil error:&error];
	    if (error) {
	        NSLog(@"attachment error %@", error);
	    }
	    content.attachments = @[att];
	    content.launchImageName = @"icon_certification_status1@2x";
	    // 2.设置声音
	    UNNotificationSound *sound = [UNNotificationSound defaultSound];
	    content.sound = sound;

	    // 3.触发模式
	    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];

	    // 4.设置UNNotificationRequest
	    NSString *requestIdentifer = @"TestRequest";
	    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifer content:content trigger:trigger1];

	    //5.把通知加到UNUserNotificationCenter, 到指定触发点会被触发
	    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
	    }];
```

The code above creates a local notification that fires after 5 seconds. Its appearance is shown below.

![1](<https://allluckly.cn/images/blog/tuogao/tougao63/1.png>)

The image shown when pulling down to expand is produced by content.launchImageName = @”icon\_certification\_status1@2x”; as illustrated below.

![1](<https://allluckly.cn/images/blog/tuogao/tougao63/2.png>)

As the example shows, creating a UNNotificationRequest requires UNMutableNotificationContent and UNTimeIntervalNotificationTrigger. I will explain the relevant classes and extensions below.

1. UNNotificationContent and UNMutableNotificationContent: immutable and mutable notification content

Notification content comes in mutable and immutable forms, much like arrays. Updating a notification later through a particular identifier uses mutable content. Both forms have the following properties:

```
	// 1.附件数组，存放UNNotificationAttachment类
	@property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments ;

	// 2.应用程序角标，0或者不传，意味着角标消失
	@property (NS_NONATOMIC_IOSONLY, copy, nullable) NSNumber *badge;

	// 3.主体内容
	@property (NS_NONATOMIC_IOSONLY, copy) NSString *body ;

	// 4.app通知下拉预览时候展示的图
	@property (NS_NONATOMIC_IOSONLY, copy) NSString *launchImageName;

	// 5.UNNotificationSound类，可以设置默认声音，或者指定名称的声音
	@property (NS_NONATOMIC_IOSONLY, copy, nullable) UNNotificationSound *sound ;

	// 6.推送内容的子标题
	@property (NS_NONATOMIC_IOSONLY, copy) NSString *subtitle ;

	// 7.通知线程的标识
	@property (NS_NONATOMIC_IOSONLY, copy) NSString *threadIdentifier;

	// 8.推送内容的标题
	@property (NS_NONATOMIC_IOSONLY, copy) NSString *title ;

	// 9.远程通知推送内容
	@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *userInfo;

	// 10.category标识
	@property (NS_NONATOMIC_IOSONLY, copy) NSString *categoryIdentifier;
```

I added explanations for the properties above. Refer to the comments when using them.

2. UNNotificationAttachment: Notification attachments

UNNotificationContent has an attachments array containing UNNotificationAttachment objects.

```
	@property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments ;
```

Apple describes UNNotificationAttachment as an attachment containing audio, image, or video content that a notification can display. For local notifications, add the attachment when creating the notification. Remote notifications require a notification service extension using UNNotificationServiceExtension.

Create an attachment with attachmentWithIdentifier:URL:options:error:. Specify the attachment file and ensure its format is supported. After creation, assign it to the content object's attachments property. For remote notifications, do this in the service extension. Supported attachment types are shown below:

![1](<https://allluckly.cn/images/blog/tuogao/tougao63/3.png>)

Here is the method for creating a UNNotificationAttachment:

```
	+ (nullable instancetype)attachmentWithIdentifier:(NSString *)identifier URL:(NSURL *)URL options:(nullable NSDictionary *)options error:(NSError *__nullable *__nullable)error;
```

### Note: URL must be a valid file path, or an error occurs.

There are 4 options properties to explain; researching these took considerable effort.

- 1. UNNotificationAttachmentOptionsTypeHintKey takes an NSString containing the file's uniform type identifier, or UTI. If omitted, the attachment's extension determines its type. Common identifiers include kUTTypeImage, kUTTypeJPEG2000, kUTTypeTIFF, kUTTypePICT, kUTTypeGIF, kUTTypePNG, and kUTTypeQuickTimeImage. You may find these types cause import errors. Apple's documentation shows that the following framework is required; use the corresponding types as follows.

Note:

The framework import is #import\<MobileCoreServices/MobileCoreServices.h\>.

Use it as follows:

```
	dict[UNNotificationAttachmentOptionsTypeHintKey] = (__bridge id _Nullable)(kUTTypeImage);
```

- 2. UNNotificationAttachmentOptionsThumbnailHiddenKey is a BOOL. YES hides the thumbnail; the default is YES. As shown:

![1](<https://allluckly.cn/images/blog/tuogao/tougao63/4.png>)

Compare with the diagram above to see which part of the image disappears.

Usage:

```
	dict[UNNotificationAttachmentOptionsThumbnailHiddenKey] =  @YES;
```

- 3. UNNotificationAttachmentOptionsThumbnailClippingRectKey crops the thumbnail. Its value is a dictionary containing a normalized CGRect: a unit rectangle with values between 1.0 and 0.0 representing the portion of the original image to display. For example, origin (0.25, 0.25) and size (0.5, 0.5) define a crop showing only the center. Use CGRectCreateDictionaryRepresentation to create the rectangle dictionary.

The explanation above is translated from Apple and is rather convoluted. The following diagram makes it simpler.

![1](<https://allluckly.cn/images/blog/tuogao/tougao63/5.png>)  
B

The entire image is treated as a normalized unit with a total scale of 1. To obtain the shaded region, use CGRect(0.5,0.5,0.25,0.25): an origin of (0.5,0.5) and dimensions of (0.25,0.25). In code, this means:

Use it as follows:

```
	dict[UNNotificationAttachmentOptionsThumbnailClippingRectKey] = (__bridge id _Nullable)((CGRectCreateDictionaryRepresentation(CGRectMake(0.5, 0.5, 0.25 ,0.25))));;
```

The method above obtains the shaded part of the image for the notification thumbnail. You should be able to see the changed thumbnail in the following example.

![1](<https://allluckly.cn/images/blog/tuogao/tougao63/6.png>)

For clarity, here are a few more coordinate examples:

```
	(0，0，0.25，0.25)左上角的最小正方形
	(0，0，0.5，0.5) 四分之一的正方形，左上角
	(0.5，0.5，0.5，0.5)四分之一的正方形，右下角
	(0.5，0，0.5，0.5)四分之一的正方形，左下角
	(0.25,0.25,0.5,0.5)最中心的正方形
```

## Important:

During debugging, I suspected an Apple bug. Repeatedly changing the thumbnail's frame still displayed the first frame I had specified. Changing the UNNotificationRequest requestIdentifer allowed the property to change. Perhaps requests with the same requestIdentifer count as one notification and require the update method to change the thumbnail. It may not be a bug after all.

- 4. UNNotificationAttachmentOptionsThumbnailTimeKey is generally used for movie attachments. It specifies which second of the movie supplies the thumbnail.

Use it as follows:

```
	dict[UNNotificationAttachmentOptionsThumbnailTimeKey] =@10;
```

Pass an NSNumber directly. For example, to use the frame at 10s as the thumbnail, write it as shown above. The specified time must fall within the movie's duration, or an error occurs.

3. UNTimeIntervalNotificationTrigger: Notification triggering modes

I introduced this briefly in !(this article; I will now explain it in detail)\[www.baidu.com\]. Here is a more detailed explanation.

1. UNPushNotificationTrigger: A remote-notification trigger, which we generally do not use directly.

2. UNTimeIntervalNotificationTrigger: a local notification delivered after an interval, repeated or not. Set timeInterval and repeats.

Usage:

```
	UNTimeIntervalNotificationTrigger *triggerOne = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
```

Explanation: the method above runs after 5 seconds. If repeats is enabled, TimeInterval must be greater than 60s, or the following error occurs: `* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'time interval must be at least 60 if repeating'`!\*\*

3. UNCalendarNotificationTrigger: A local notification that fires at a date or time, with optional repetition. For example, to notify at 8 every day, set the appropriate dateComponents value to 8 and repeats to YES.

```
	// 周一早上 8：00 上班
	NSDateComponents *components = [[NSDateComponents alloc] init];
	// 注意，weekday是从周日开始的，如果想设置为从周一开始，大家可以自己想想~
	components.weekday = 2;
	components.hour = 8;
	UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
```

4. UNLocationNotificationTrigger: A location-based local notification. To use it, import

## the system library with import\<CoreLocation/CoreLocation.h\>. Example code follows:

```
	//1、如果用户进入或者走出某个区域会调用下面两个方法
	- (void)locationManager:(CLLocationManager *)manager
	didEnterRegion:(CLRegion *)region
	- (void)locationManager:(CLLocationManager *)manager
	didExitRegion:(CLRegion *)region代理方法反馈相关信息

	//2、一到某个经纬度就通知，判断包含某一点么
	// 不建议使用！！！！！！CLRegion *region = [[CLRegion alloc] init];// 不建议使用！！！！！！


	CLCircularRegion *circlarRegin = [[CLCircularRegion alloc] init];
	[circlarRegin containsCoordinate:(CLLocationCoordinate2D)];

	UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:circlarRegin repeats:NO];
```

I recommend CLCircularRegion, a subclass of CLRegion. Apple's point-containment method on CLRegion is deprecated, and Apple recommends CLCircularRegion instead.

If you like the article, please follow me. Thank you! Please credit the source when republishing. I will keep writing useful articles in return.

I will add more content later. Stay tuned!

---

Recommended reading: [Implement an iOS launch-screen advertisement in minutes](<https://allluckly.cn/en/journal/2016-06-12-adding-a-launch-advertisement-to-an-ios-app/>)

