• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ChenYilong/iOS10AdaptationTips: for iOS10 in [ObjC, Swift, English, 中文] {...} ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

ChenYilong/iOS10AdaptationTips

开源软件地址:

https://github.com/ChenYilong/iOS10AdaptationTips

开源编程语言:

Objective-C 87.6%

开源软件介绍:

iOS10AdaptationTips

Reference:iOS9AdaptationTips.

Notification

User Notifications : both a new and old framework

If you diff SDK 'iOS 10.0'(Xcode 8) and SDK 'iOS 9.0' with this command below, you will find six UIKit classes related to notifications are deprecated in SDK 'iOS 10.0'(Xcode 8) .

UIKit9Dir="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/UIKit.framework"
UIKit10Dir="/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/UIKit.framework"

OptIgnore=--ignore-matching-lines='//.*Copyright'
DIFFBIN=/usr/bin/diff
$DIFFBIN -U 1 -r -x '*.tbd' -x '*.modulemap' $OptIgnore $UIKit9Dir $UIKit10Dir|egrep -C 1 "NS_CLASS_DEPRECATED_IOS.*"|grep interface

All of them are:

  1. UILocalNotification
  2. UIMutableUserNotificationAction
  3. UIMutableUserNotificationCategory
  4. UIUserNotificationAction
  5. UIUserNotificationCategory
  6. UIUserNotificationSettings

Old api also works fine with SDK 'iOS 10.0'(Xcode 8) , but we had better use the APIs in the User Notifications framework instead.

In addation to these classes, the handleActionWithIdentifier:forLocalNotification:, handleActionWithIdentifier:forRemoteNotification:, didReceiveLocalNotification:withCompletion:, and didReceiveRemoteNotification:withCompletion: WatchKit methods. Use handleActionWithIdentifier:forNotification: and didReceiveNotification:withCompletion: instead. Also the notification-handling methods in WKExtensionDelegate, such as didReceiveRemoteNotification: and handleActionWithIdentifier:forRemoteNotification:. Instead of using these methods, first create a delegate object that adopts the UNUserNotificationCenterDelegate protocol and implement the appropriate methods. Then assign the delegate object to the delegate property of the singleton UNUserNotificationCenter object.

SDK 'iOS 10.0'(Xcode 8) introduces the User Notifications framework (UserNotifications.framework), independent from UIKit, which supports the delivery and handling of local and remote notifications. so it's' both a new and old framework. You use the classes of this framework to schedule the delivery of local notifications based on specific conditions, such as time or location. Apps and app extensions can use this framework to receive and potentially modify local and remote notifications when they are delivered to the user’s device.

Also introduced in SDK 'iOS 10.0'(Xcode 8) , the User Notifications UI framework (UserNotificationsUI.framework) lets you customize the appearance of local and remote notifications when they appear on the user’s device. You use this framework to define an app extension that receives the notification data and provides the corresponding visual representation. Your extension can also respond to custom actions associated with those notifications.

I'll introduce the User Notifications framework in two parts:

  1. Local Notification
  2. Remote Notification

LocalNotification : write everything in one place

Someone may have the same question with this guy: enter image description here

It is impossible for the first question, but local notification may be the best way to help you In terms of waking the app at a certain time, even a certain place. Because LocalNotification is just for scheduling the delivery of local notifications based on specific conditions, such as time or location.

LocalNotification has a limit, you can't trigger a block of code to run when the notification is fired. You can, however, trigger a block of code to execute with a UNNotificationAction by adding an action to your notification and using userNotificationCenter(_:didReceive:withCompletionHandler:) on UNUserNotificationCenter.currentNotificationCenter(). That is to say, it's impossiable to run a snippet in background at a certain time, without notifiying user. This feature is limited byond iOS8.

schedule the delivery of local notifications based on time

Big Diff:

  1. Now you can either present alert, sound or increase badge while the app is in foreground too with SDK 'iOS 10.0'(Xcode 8)
  2. Now you can handle all event in one place when user tapped (or slided) the action button, even while the app has already been killed.
  3. Support 3D touch instead of sliding gesture.
  4. Now you can remove specifical local notification just by one row code.
  5. Support Rich Notification with custom UI.

I write a Demo here: iOS10AdaptationTips .

With Swift implemation:

  1. import UserNotifications

    ///    Notification become independent from UIKit
    @import UserNotifications;
    
  2. request authorization for localNotification

        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
            // Enable or disable features based on authorization.
        }
    
  3. schedule localNotification

  4. update application icon badge number

    @IBAction  func triggerNotification(){
        let content = UNMutableNotificationContent()
        content.title = NSString.localizedUserNotificationString(forKey: "Elon said:", arguments: nil)
        content.body = NSString.localizedUserNotificationString(forKey: "Hello Tom!Get up, let's play with Jerry!", arguments: nil)
        content.sound = UNNotificationSound.default()
        content.badge = UIApplication.shared().applicationIconBadgeNumber + 1;
        content.categoryIdentifier = "com.elonchan.localNotification"
        // Deliver the notification in five seconds.
        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 60.0, repeats: true)
        let request = UNNotificationRequest.init(identifier: "FiveSecond", content: content, trigger: trigger)
    
        // Schedule the notification.
        let center = UNUserNotificationCenter.current()
        center.add(request)
    }
    
    @IBAction func stopNotification(_ sender: AnyObject) {
        let center = UNUserNotificationCenter.current()
        center.removeAllPendingNotificationRequests()
        // or you can remove specifical notification:
        // center.removePendingNotificationRequests(withIdentifiers: ["FiveSecond"])
    }
    

With Objective-C implemation:

  1. import UserNotifications

    ///    Notification become independent from UIKit
    @import UserNotifications;
    
  2. request authorization for localNotification

    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
                              if (!error) {
                                  NSLog(@"request authorization succeeded!");
                                  [self showAlert];
                              }
                          }];
    
  3. schedule localNotification

  4. update application icon badge number

        //        //Deliver the notification at 08:30 everyday
        //        NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
        //        dateComponents.hour = 8;
        //        dateComponents.minute = 30;
        //        UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents repeats:YES];
        
        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
        content.title = [NSString localizedUserNotificationStringForKey:@"Elon said:" arguments:nil];
        content.body = [NSString localizedUserNotificationStringForKey:@"Hello Tom!Get up, let's play with Jerry!"
                                                             arguments:nil];
        content.sound = [UNNotificationSound defaultSound];
        
        /// 4. update application icon badge number
        content.badge = NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + 1);
        // Deliver the notification in five seconds.
        UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger
                                                      triggerWithTimeInterval:5.f repeats:NO];
        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond"
                                                                              content:content trigger:trigger];
        /// 3. schedule localNotification
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
            if (!error) {
                NSLog(@"add NotificationRequest succeeded!");
            }
        }];
    

Go to here for more information: iOS10AdaptationTips .

updated:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'time interval must be at least 60 if repeating'

let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 60, repeats: true)

then it will appear like this:

iOS Version iOS10 iOS9
Request Authorization enter image description here enter image description here
In Background enter image description here enter image description here
Lock Screen enter image description here enter image description here
If Repeat by default enter image description here enter image description here
3D Touch enter image description here not support
  1. Now you can either present alert, sound or increase badge while the app is in foreground too with SDK 'iOS 10.0'(Xcode 8)
  2. Now you can handle all event in one place when user tapped (or slided) the action button, even while the app has already been killed.
  3. Support 3D touch instead of sliding gesture.
  4. Now you can remove specifical local notification just by one row code.
- (void)stopNotification:(id)sender {
   if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
       UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
       // remove all local notification:
//        [center removeAllPendingNotificationRequests];
       // or you can remove specifical local notification:
        [center removePendingNotificationRequestsWithIdentifiers:@[ CYLInviteCategoryIdentifier ]];
   } else {
       // remove all local notification:
//        [[UIApplication sharedApplication] cancelAllLocalNotifications];
       // or you can remove specifical local notification:
       NSString *specificalIDToCancel = CYLInviteCategoryIdentifier;
       UILocalNotification *notificationToCancel = nil;
       for(UILocalNotification *aNotif in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
           if([[aNotif.userInfo objectForKey:@"CategoryIdentifier"] isEqualToString:specificalIDToCancel]) {
               notificationToCancel = aNotif;
               break;
           }
       }
       if(notificationToCancel) {
           [[UIApplication sharedApplication] cancelLocalNotification:notificationToCancel];
       }
   }
}

By the way, you can use this code to check Xcode Version:

#define XCODE_VERSION_GREATER_THAN_OR_EQUAL_TO_8    __has_include(<UserNotifications/UserNotifications.h>)

###Remote Push Notification

It's really samilar with Local Notification:

Reigster method may be the biggist different:

I'll show how to register with Objective-C method:

   - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [self registerForRemoteNotification];
        . . .
    }


    - (void)registerForRemoteNotification {
        if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
            UNUserNotificationCenter *uncenter = [UNUserNotificationCenter currentNotificationCenter];
            [uncenter setDelegate:self];
            [uncenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert+UNAuthorizationOptionBadge+UNAuthorizationOptionSound)
                                    completionHandler:^(BOOL granted, NSError * _Nullable error) {
                                        [[UIApplication sharedApplication] registerForRemoteNotifications];
                                        NSLog(@"%@" , granted ? @"success to request authorization." : @"failed to request authorization .");
                                    }];
            [uncenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                NSLog(@"%s\nline:%@\n-----\n%@\n\n", __func__, @(__LINE__), settings);
                if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
                    //TODO:
                } else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
                    //TODO:
                } else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
                    //TODO:
                }
            }];
        }
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
        if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
            UIUserNotificationType types = UIUserNotificationTypeAlert |
                                           UIUserNotificationTypeBadge |
                                           UIUserNotificationTypeSound;
            UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];

            [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
            [[UIApplication sharedApplication] registerForRemoteNotifications];
        } else {
            UIRemoteNotificationType types = UIRemoteNotificationTypeBadge |
                                             UIRemoteNotificationTypeAlert |
                                             UIRemoteNotificationTypeSound;
            [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
        }
    #pragma clang diagnostic pop
    }

Here is a demo: iOS10AdaptationTips.

schedule the delivery of local notifications based on location

If your iPhone installed Foursquare-app, you will deliver notification when you enters or leaves a geographic region. How to do that?

just trigger with this:

@interface UNLocationNotificationTrigger : UNNotificationTrigger

@property (NS_NONATOMIC_IOSONLY, readonly, copy) CLRegion *region;

+ (instancetype)triggerWithRegion:(CLRegion *)region repeats:(BOOL)repeats __WATCHOS_PROHIBITED;

@end

some little error

Check dependencies Signing for Your-Prject-Name requires a development team. Select a development team in the Target Editor. Warning: The Copy Bundle Resources build phase contains this target's Info.plist file '/Users//Info.plist'. Code signing is required for product type 'Application' in SDK 'iOS 10.0'

ATS

Reference : Security and Privacy Enhancements

Security

Access privacy-sensitive data

Before you access privacy-sensitive data like Camera, Contacts, and so on, you must ask for the authorization, your app will crash when you access them.Then Xcode will log like:

This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSContactsUsageDescription key with a string value explaining to the user how the app uses this data.

How to deal with this? As apple say:

You must statically declare your app’s intended use of protected data classes by including the appropriate purpose string keys in your Info.plist file.

Open the file in your project named info.plist, right click it, opening as Source Code, paste this code below to it. Or you can open info.plist as Property List by default, click the add button, Xcode will give you the suggest completions while typing Privacy - with the help of keyboard ⬆️ and ⬇️.

The list of frameworks that count as private data is a long one:

Contacts, Calendar, Reminders, Photos, Bluetooth Sharing, Microphone, Camera, Location, Health, HomeKit, Media Library, Motion, CallKit, Speech Recognition, SiriKit, TV Provider.

Remember to write your description why you ask for this authorization, between <string> and </string>, or your app will be rejected by apple:


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap