[ios] 앱이 열려 있고 포 그라운드에있을 때 주식 iOS 알림 배너를 표시합니까?

Apple의 공식 iOS 메시지 앱이 열려 있고 포 그라운드에있을 때 다른 연락처의 새 메시지가 주식 기본 iOS 알림 알림 배너를 트리거합니다. 아래 이미지를 참조하십시오.

App Store의 타사 앱에서 가능합니까? 앱이 열려 있고 포 그라운드에있는 동안 앱에 대한 로컬 및 / 또는 푸시 알림 ?

내 앱을 테스트 할 때 알림이 수신되지만 iOS 경고 UI가 표시되지 않습니다 .

그러나이 동작 Apple의 공식 메시지 앱에서 볼 수 있습니다.

메시지가 열려 있고 포 그라운드에 있습니다.  여전히 알림 경고를 표시합니다.

로컬 및 원격 통지 프로그래밍 가이드는 말한다 :

운영 체제가 로컬 알림 또는 원격 알림을 전달하고 대상 앱이 포 그라운드에서 실행되지 않는 경우 경고 , 아이콘 배지 번호 또는 사운드를 통해 사용자에게 알림을 표시 할 수 있습니다 .

알림이 전달 될 때 앱이 포 그라운드 에서 실행중인 경우 앱 대리자는 로컬 또는 원격 알림을받습니다.

예, 포 그라운드에있는 동안 알림 데이터 를 받을 수 있습니다 . 하지만 기본 iOS 알림 경고 UI 를 표시 할 방법이 없습니다 .

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    // I know we still receive the notification `userInfo` payload in the foreground.
    // This question is about displaying the stock iOS notification alert UI.

    // Yes, one *could* use a 3rd party toast alert framework. 
    [self use3rdPartyToastAlertFrameworkFromGithub]
}

메시지는 포 그라운드에있는 동안 경고를 표시하기 위해 비공개 API를 사용합니까?

이 질문의 목적을 위해 github 등에서 타사 “토스트”팝업 경고제안하지 마십시오 . 재고, 기본 iOS 로컬 또는 푸시 알림 경고 UI 사용하여 수행 할 수있는 경우에만 관심이 있습니다. 응용 프로그램이 열려 있고 포 그라운드에 있습니다.



답변

iOS 10UNUserNotificationCenterDelegate 은 앱이 포 그라운드에있는 동안 알림을 처리하기위한 프로토콜을 추가합니다 .

UNUserNotificationCenterDelegate프로토콜은 알림을 수신하고 작업을 처리하는 방법을 정의합니다. 앱이 포 그라운드에있을 때 도착 알림은 시스템 인터페이스를 사용하여 자동으로 표시되는 대신 위임 객체로 전달됩니다.

빠른:

optional func userNotificationCenter(_ center: UNUserNotificationCenter,
                     willPresent notification: UNNotification,
      withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)

목표 -C :

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;

UNNotificationPresentationOptions의 플래그는 사용자가 지정 할 수 있도록 UNNotificationPresentationOptionAlert알림이 제공하는 텍스트를 사용하여 경고를 표시합니다.

iOS 10의 새로운 기능인 앱이 열려 있고 포 그라운드 에있는 동안 경고를 표시 할 수 있기 때문에 중요 합니다 .


샘플 코드 :

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Set UNUserNotificationCenterDelegate
        UNUserNotificationCenter.current().delegate = self

        return true
    }

}

// Conform to UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter,
           willPresent notification: UNNotification,
           withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
    {
        completionHandler(.alert)
    }

}


답변

앱이 포 그라운드 상태 일 때 배너 메시지를 표시하려면 다음 방법을 사용하십시오.

iOS 10 이상, Swift 3 이상 :

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .badge, .sound])
}


답변

편집하다:

이제 iOS 10에서 전경 경고가 가능합니다! 이 답변을 참조하십시오 .

iOS 9 이하 :

앱이 열려 있고 포 그라운드에있을 때 주식 iOS 알림 경고를 표시 할 수없는 것 같습니다. Messages.app은 비공개 API를 사용해야합니다.

시스템은 앱이 이미 맨 앞에있을 때 경고를 표시하거나 앱 아이콘에 배지를 표시하거나 소리를 재생하지 않습니다. – UILocalNotification 워드 프로세서

UIApplicationDelegate방법은 것입니다 여전히 로컬 또는 원격 통지에 대응하기 위해 귀하의 응용 프로그램을 허용 호출 :

application:didReceiveLocalNotification:
application:didReceiveRemoteNotification:

그러나 주식 기본 iOS 알림 알림 배너 UI는 비공개 API를 사용해야하는 Apple의 Messages.app 에서처럼 표시되지 않습니다 .

할 수있는 최선의 방법은 자체 경고 배너를 롤링하거나 기존 프레임 워크를 사용하는 것입니다.

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    // Use a 3rd party toast alert framework to display a banner 
    [self toastAlertFromGithub]
}

이 동작에 대한 레이더를 여기에서 열었습니다. rdar://22313177


답변

앱이 열려있는 동안 알림을 표시하려면 수동으로 처리해야합니다. 그래서 아래에서 내가하는 일은 일단 수신 된 알림을 처리하는 것입니다.

AppDelegate.m에 아래 모두 추가

  1. 알림을위한 통화 처리
  2. 보기를 만들고 AppIcon, 알림 메시지를 추가하고 애니메이션으로 표시
  3. 터치하면 제거 할 터치 인식기를 추가하거나 애니메이션으로 5 초 안에 제거합니다.

이것이 괜찮은 해결책인지 알려주십시오. 나를 위해 잘 작동했지만 이것이 올바른 방법인지 확실하지 않습니다.

- (void)application:(UIApplication *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {


NSString *notifMessage = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];

//Define notifView as UIView in the header file
[_notifView removeFromSuperview]; //If already existing

_notifView = [[UIView alloc] initWithFrame:CGRectMake(0, -70, self.window.frame.size.width, 80)];
[_notifView setBackgroundColor:[UIColor blackColor]];

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,15,30,30)];
imageView.image = [UIImage imageNamed:@"AppLogo.png"];

UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 15, self.window.frame.size.width - 100 , 30)];
myLabel.font = [UIFont fontWithName:@"Helvetica" size:10.0];
myLabel.text = notifMessage;

[myLabel setTextColor:[UIColor whiteColor]];
[myLabel setNumberOfLines:0];

[_notifView setAlpha:0.95];

//The Icon
[_notifView addSubview:imageView];

//The Text
[_notifView addSubview:myLabel];

//The View
[self.window addSubview:_notifView];

UITapGestureRecognizer *tapToDismissNotif = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                    action:@selector(dismissNotifFromScreen)];
tapToDismissNotif.numberOfTapsRequired = 1;
tapToDismissNotif.numberOfTouchesRequired = 1;

[_notifView addGestureRecognizer:tapToDismissNotif];


[UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{

    [_notifView setFrame:CGRectMake(0, 0, self.window.frame.size.width, 60)];

} completion:^(BOOL finished) {


}];


//Remove from top view after 5 seconds
[self performSelector:@selector(dismissNotifFromScreen) withObject:nil afterDelay:5.0];


return;


}

//If the user touches the view or to remove from view after 5 seconds
- (void)dismissNotifFromScreen{

[UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{

    [_notifView setFrame:CGRectMake(0, -70, self.window.frame.size.width, 60)];

} completion:^(BOOL finished) {


}];


}


답변

다음은 앱이 포 그라운드 또는 오픈 스테이지, iOS 10 및 Swift 2.3 일 때 푸시 알림을 수신하는 코드입니다.

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
{
     completionHandler([UNNotificationPresentationOptions.Alert,UNNotificationPresentationOptions.Sound,UNNotificationPresentationOptions.Badge])
}

알림의 userInfo에 액세스해야하는 경우 코드를 사용하십시오. notification.request.content.userInfo

이 메서드 userNotificationCenter(_:willPresent:withCompletionHandler:)는 속성을 페이로드에 추가하는 경우에만 호출됩니다 content-available:1. 최종 페이로드는 다음과 같아야합니다.

{
     "aps":{
          "alert":"Testing.. (7)",
          "badge":1,"sound":"default"
     },
     "content-available":1
}


답변

UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.body = body;
content.userInfo = userInfo;
content.sound = [UNNotificationSound defaultSound];
[content setValue:@(YES) forKeyPath:@"shouldAlwaysAlertWhileAppIsForeground"];

UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"Notif" content:content trigger:nil];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
    DLog(@"Error:%@", error);
}];

iOS 10에서 앱이 활성화되면 푸시 알림을 표시 할 수 있습니다 .

  1. 서버의 푸시 알림은 자동 이어야합니다 .

  2. 서버에서 원격 알림을 받으면 로컬 알림을 보내고 keyPath 의 값을 설정합니다 . shouldAlwaysAlertWhileAppIsForeground = True


답변

알림을 직접 처리하고 맞춤 알림을 표시 할 수 있습니다. Viber, Whatsapp 및 BisPhone과 같은 앱은이 접근 방식을 사용합니다.

타사 맞춤 알림의 한 가지 예는 CRToast 입니다.

앱이 포 그라운드에있는 동안 로컬 알림을 예약하면 주식 iOS 알림이 표시되지 않습니다.

if (application.applicationState == UIApplicationStateActive ) {
     UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    localNotification.userInfo = userInfo;
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    localNotification.alertBody = message;
    localNotification.fireDate = [NSDate date];
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}