[ios tutorial] Local Notification
-
앱이 Foreground 상태가 아닐 때 사용자에게 어떤 정보를 알리기 위해 주로 사용한다.
앱이 Foreground 상태일 때에는 Notification 이 표시되지 않고, Callback 을 받아 따로 처리해야 한다.
-
사용자는 Local Notification 과 Remote Notification (Push) 에 대한 차이를 알기 어렵다.
둘 다 스크린상의 alert 나 banner, app badge, 사운드 등의 형태로 알람을 제공한다.
Permission
-
iOS8 부터는 badge icons, alert message 표시, 소리 재생 등의 기능을 사용하기 위해서는 interaction type 을 등록 & User 의 Permission 을 받아야 한다.
( 이전 버전에서는 Remote 에 대해서만 registerForRemoteNotificationTypes: 를 통해 등록했었다. )
UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert);
UIUserNotificationSettings* mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
-
registerUserNotificationSettings: 를 호출하면 iOS 는 user 에게 이 특정 interaction 을 허락할지 묻는 prompt 를 띄운다.
유저가 허락을 하던 안 하던 application:didRegisterUserNotificationSettings: 가 불린다.
허락을 한 경우에는 전달되는 UIUserNotificiationSettings 에 요청한 settings 값들이 들어있고,
실패한 경우에는 전달되는 UIUserNotificationSettings 에 None 세팅 값이 들어간다.
UserNotification 을 동의한 경우 Setting 화면
UserNotification 을 거부한 경우 Setting 화면
-
User가 Settings 를 통해 설정을 바꿀 수 있기 때문에 App Launch 시에 항상 registerUserNotificationSettings: 를 부르고 application:didRegisterUserNotificationSettings: 를 통해 현재 가용할 수 있는 Notification Type 이 무엇인지 볼 필요가 있다.
혹은 UIApplication 의 currentUserNotificationSettings 를 통해 현재 사용 가능한 notification type 을 얻어올 수도 있다.
Notification 등록
-
UILocalNotification 의 속성은 크게 아래 3가지
Scheduled time : 알람 발생 시각, 반복 설정 및 반복 주기 설정, 타임존 설정
Notification type : 알림 메시지, 액션 버튼 타이틀, 뱃지 아이콘, 알림 사운드 ( iOS8 부터 가능 )
Custom data : 사용자 정보
-
UILocalNotification 와 UIApplication 이 사용된다.
- (void)fireLocalNotification{
UILocalNotification *noti = [[UILocalNotification alloc] init];
noti.fireDate = [NSDate dateWithTimeIntervalSinceNow:5]; // 5초 후 알림 발생
noti.timeZone = [NSTimeZone systemTimeZone];
noti.alertBody = @“Thie is alarm message”;
noti.alertAction = @“Action”; // 알림이 Alert type 일 때 OK 버튼의 Title 을 설정 or LockScreen Slide 에서 사용 nil 일 경우 디폴트 값 사용됨.
noti.alertTitle = @“Title”; // iOS 8.2 부터 & Only Apple Watch
noti.applicationIconBadgeNumber = 1;
noti.soundName = UILocalNotificationDefaultSoundName; // nil 이면 no sound
noti.userInfo = @{ “User Info” : “My User Info” };
[[UIApplication sharedApplication] scheduleLocalNotification:noti];
}
// scheduledLocalNotifications 로 한번에 여러개의 Notification 을 동시에 등록할 수도 있다.
아래 property 들도 있으니 필요하면 공부해서 사용하시길!!
NSCalendarUnit repeatInterval
NSCalendar* repeatCalendar
CLRegion* region
BOOL regionTriggersOnce
NSString* alertLaunchImage
Notification 응답
-
Notification 을 클릭하면 ( 잠금화면에서는 락을 푸는 작업이 추가되어야 한다. ) application delegate 의 willFinishLaunchingWithOptions: 와 didFinishLaunchingWithOptions: 가 호출된다.
이 함수는 앱을 최초 실행할 때에도 (process kill 상태) 수행되는데, launchOptions 값을 통해 구분이 가능하다.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UILocalNotification* localNoti = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if (localNoti){
// localNoti 를 통해 수행되었다.
}
}
( Remote 의 경우 UIApplicationLaunchOptionsRemoteNotificationKey 에 UILocalNotification 이 들어 있다. )
-
앱이 실행 중인 경우에는 ( Background, Foreground 상관 없이 ) application delegate 의 didReceiveLocalNotification: 메소드가 호출된다.
( Remote 의 경우 didReceiveRemoteNotification:fetchCompletionHandler: 가 불린다. )
-
앱이 실행 중이며 Background 상태일 때에는 알림이 표시되고, 해당 알림을 통해 앱에 진입하면 didReceiveLocalNotification 도 불린다.
그러나 Foreground 상태에서는 알림 표시가 안 되고 didReceiveLocalNotification 만 호출되므로, 알림창을 띄워주고 싶다면 여기서 잘 띄워주어야 한다.
그럼 Background, Foreground 상태 모두에 didReceiveLocalNotification 이 불리는 데 어떻게 상태 구분을 할까?
application.applicationState == UIApplicationStateActive 로 구분하면 된다. ( 혹은 UIApplicationStateInactive )
typedef NS_ENUM(NSInteger, UIApplicationState) {
UIApplicationStateActive, // 0, foreground 에서 받았을 때
UIApplicationStateInactive, // 1, background 에서 받아서 들어왔을 때
UIApplicationStateBackground
}
-
User 가 Custom action button 을 누르면 application:handleActionWithIdentifier:forLocalNotification:completeHandler: 가 불린다.
Notification 취소
-
UIApplication 의 cancelAllLocalNotifications 와 cancelLocalNotification: 메소드를 이용하면 된다.
-
Notification 의 취소는 2가지 형태의 취소가 가능하다.
알림 대기 중인 알림의 취소
이미 도착해서 알림 센터 목록에 등록된 알림의 취소
-
이미 도착한 알림은 didFinishLaunchingWithOptions: 와 didReceiveLocalNotification: 에서 cancelLocalNotification 을 통해 제거할 수 있는데, 이는 실제 알림은 fire 된 상태이고, ( 앱 실행 상태에 따라 알림이 유저에게 보여졌을 수도 보여지지 않았을 수도 있다. ) 알림센터에만 보이지 않게 한다.
-
알림 대기 중인 알림의 취소는 같은 값을 갖는 UILocalNotification 을 만들어 제거해주면 된다.
Actionable Notification or Interactive Notification
-
Actionable Notification 이 도착하면 시스템은 등록한 Action 에 대해 (1개 혹은 2개의) 버튼들을 추가해준다.
-
UIMutableUserNotificationAction 을 만들고, UIUserNotificationCategory 에 적용한 후, UIUserNotificationSettings 를 통해 등록해 주면 된다.
-
Notification 의 버튼들을 통해서 foreground 로 만들지 않고도 미리 정의한 특정 액션을 수행할 수 있다.
미리 정의한 특정 액션을 category 라는 용어를 사용하고, 각 액션은 identifier 를 가지고 있다.
-
Actionable Notification 등록은 아래의 과정처럼 한다.
UIMutableUserNotificationAction* action1 = [[UIMutableUserNotificationAction alloc] init];
[action1 setActivationMode:UIUserNotificationActivationModeBackground];
[action1 setTitle:@"Action1"];
[action1 setIdentifier:@"Action1"];
[action1 setDestructive:NO];
[action1 setAuthenticationRequired:NO];
UIMutableUserNotificationAction* action2 = [[UIMutableUserNotificationAction alloc] init];
[action2 setActivationMode:UIUserNotificationActivationModeBackground];
[action2 setTitle:@"Action2"];
[action2 setIdentifier:@"Action2"];
[action2 setDestructive:NO];
[action2 setAuthenticationRequired:NO];
UIMutableUserNotificationCategory* category = [[UIMutableUserNotificationCategory alloc] init];
[category setIdentifier:@"Category"];
[category setActions:@[action1, action2] forContext:UIUserNotificationActionContextDefault];
NSSet* categories = [NSSet setWithObject:category];
UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge );
UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
-
Action 을 하나만 등록하는 경우에는 One Button 만 나온다.
Action 을 2개 넘게 등록하는 경우에는 Banner 에서는 먼저 등록한 2개의 버튼만 나오고, Alert 의 옵션에서는 모두 나온다.
-
setActivationMode
UIUserNotificationActivationModeBackground : 앱을 구동시키지 않고 작업을 수행한다.
UIUserNotificationActivationModeForeground : 앱을 구동시키면서 작업을 수행한다.
setDestructive :
true/false 로 선택하며, true 일 경우 해당 버튼이 빨간색으로 강조된다.
Banner 에서는 강조되지 않고, Swipe 로 Action 을 수행할 때만 유효하다.
setAuthenticationRequired :
activationMode 를 Background 로 했을 때만 & LockScreen 에서 유효한 값이며, true/false 로 선택한다.
true 를 주게 되면 User 가 해당 작업을 수행하기 위해 unlock 작업을 수행해야 한다.
설정한 암호가 없다면 바로 수행된다.
-
Context Type
UIUserNotificationActionContextDefault
Alert 형태일 때 “옵션” 을 주고, 그 안에서 모든 action 을 수행할 수 있는 형태. Banner 에서는 2개의 버튼까지만 표시된다.
UIUserNotificationActionContextMinimal
Alert 형태일 때 “옵션” 대신 정해진 UILocalNotification 자체에 설정된 Action 만 표시한다. 추가 Action 을 수행할 수 없다. Banner 형태일때는 2개의 버튼까지만 동일하게 표시된다.
-
Remote Push 로 이 Notification 을 사용하려면 다음과 같은 양식으로 보내면 된다.
"aps" : {
"alert" : "Pull down to interact.",
"category" : “Category"
}
-
해당 카테고리의 Notification 이 떴을 때 버튼은 2개가 뜰 것이고, 해당 버튼을 클릭했을 때 수행할 액션들은 application:handleActionWithIdentifier:forLocalNotification:completionHandler: 혹은 application:handleActionWithIdentifier:forRemoteNotification:completeHandler: 에서 처리하면 된다.
-
UILocalNotification 을 사용할 때 category 에 해당 category 명을 주면 그 Category 로 작동한다.
Action1, Action2 를 순서대로 등록하면 Action1 버튼이 오른쪽에, Action2 버튼이 왼쪽에 등장한다.
iOS9 의 Behavior
-
iOS9 에서는 UIMutableUserNotificationAction 에 Behavior 를 줄 수 있다.
Behavior 에는 UIUserNotificationActionBehaviorDefault 와 UIUserNotificationActionBehaviorTextInput 이 올 수 있는데, UIUserNotificationActionBehaviorTextInput 을 선택하면, 해당 버튼을 선택한 순간 Text 를 바로 입력할 수 있다.
-
Text Input 에 대한 Callback 은 application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler: 혹은 application:handleActionWithIdentifier:forRemoteNotification:withResponseInfo:completionHandler: 로 들어온다.
Response 는 Dict 형인데 UIUserNotificationActionResponseTypedTextKey 에 입력된 값이 들어간다.
-
Category Action 이 한 개일때는 바로 Input 이 등장하며, 2개 이상일 때에는 해당 버튼을 눌렀을 때 Input 이 등장한다.
LockScreen과 Alert Type 에서는 Input 이 바로 등장할 수 없어, Action 이 하나일 때에도 버튼을 눌렀을 때 Input 이 등장한다.
기타
-
iOS 디바이스는 알림을 최신 64개로 제한한다.
이를 초과하는 알림에 대해서는 현재 기준으로 최근순으로 64개만 남기고 나머지를 버린다.
-
Location Notification 이란 것도 있다.
이건 User 가 특정 지역에 진입하면 notification 이 오는 형태이다.
-
LocalNotification 은 폰을 껐다 켜도 Expire 되지 않은 것들은 사라지지 않는다!!!!
정리
-
LocalNotification 과 RemoteNotification 은 UI 상 User 가 구분하기 어렵다.
-
Noti 형태는 Banner, Alert 가 있으며, Banner 가 Default 이다.
-
iOS8 부터는 application 의 registerUserNotificationSettings: 함수를 통해 User로 부터 Permission 동의를 얻어야 Noti 사용이 가능하다.
-
UIUserNotificationType 을 통해 Alert, Sound, Badge 에 대한 권한을 부여할 수 있다.
UIUserNotificationAction 을 통해 Custom Action (Interactive, Actionable) 을 만들고, UIMutableUserNotificationCategory 에 해당 Action 들을 등록하여 Action 들의 Category 를 만들 수 있다.
UIUserNotificationSettings 를 통해 Type 과 Category 들의 Set 을 합쳐 Setting 을 만들 수 있고, 이 녀석을 registerUserNotificationSettings 를 통해 등록한다.
-
UILocalNotification 에 속성들을 부여해서 Notification 을 만들 수 있고, UIApplication 의 scheduleLocalNotification 함수를 통해 해당 알람을 등록할 수 있다.
-
application:didFinishLaunchingWithOptions: 를 통해 Noti 를 클릭하여 수행한 Action 을 받을 수 있다.
Options 로 전달되는 Dict 의 UIApplicationLaunchOptionsLocalNotificationKey 에 Notification 이 들어있다.
-
Custom Action 의 경우 application:handleActionWithIdentifier:forLocalNotification:completionHandler: 를 통해 Callback 을 받을 수 있고,
iOS9 부터 사용 가능한 TextField Behavior 의 경우 application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler: 를 통해 Callback 을 받을 수 있다.
-
알림 속성들과 알림 방식 ( Banner, Alert ), 그리고 상황 ( Foregound, Background, LockScreen ) 에 따라 알림에 대한 operation 이 조금씩 다르기 때문에 Detail 한 Control 을 위해서라면 해당 상황에 대한 Test 를 해봄을 추천한다.
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[ios] .c 파일을 import 한 후 build 가 안 된다면 pch 파일을 확인해봐라. (0) | 2018.01.31 |
---|---|
[ios] 압축, 압축해제 ( archive, unarchive ) (0) | 2018.01.30 |
[ios tutorial] UIImage RenderingMode ( Template Image ) (0) | 2018.01.28 |
[도서 목차 정리] ] OS X 구조를 이해하면서 배우는 Objective-C (0) | 2018.01.13 |
[Objective-C] 기타 (0) | 2018.01.12 |
댓글