Uygulamanız açıkken ve ön plandayken hisse senedi iOS bildirim başlığı mı görüntülüyorsunuz?


123

Apple'ın resmi iOS Mesajları uygulaması açıkken ve ön planda olduğunda, diğer kişilerden gelen yeni mesajlar bir hisse senedi, yerel iOS bildirim uyarı başlığını tetikler. Aşağıdaki resme bakın.

Bu, App Store'daki 3. parti uygulamalarda mümkün mü? Uygulamanız açıkken ve ön plandayken uygulamanız için Yerel ve / veya Push Bildirimleri ?

Uygulamamı test ederken bildirimler alınıyor ancak iOS uyarı kullanıcı arayüzü gösterilmiyor .

Ama bu davranış olduğunu Apple'ın resmi Mesajlar uygulamasında görülme:

Mesajlar açık ve ön plandadır.  Hala bir bildirim uyarısı gösteriyor.

Yerel ve Uzak Bildirim Programlama Kılavuzu diyor ki:

İşletim sistemi yerel bir bildirim veya uzaktan bildirim gönderdiğinde ve hedef uygulama ön planda çalışmadığında , kullanıcıya bir uyarı , simge rozet numarası veya ses yoluyla bildirimi sunabilir .

Bildirim teslim edildiğinde uygulama ön planda çalışıyorsa , uygulama temsilcisi yerel veya uzaktan bildirim alır.

Yani evet, ön plandayken bildirim verilerini alabiliyoruz . Ancak yerel iOS bildirim uyarı kullanıcı arayüzünü sunmanın bir yolunu göremiyorum .

-(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]
}

Mesajlar ön plandayken uyarıyı görüntülemek için özel bir API kullanıyor mu?

Bu sorunun amacına uygun olarak, pop-up uyarıları "tost" herhangi bir 3. parti önermek etmeyiniz sadece bu kullanılarak yapılabilir ilgileniyorum, ben github veya vb , yerel iOS stok UI uyarıları Yerel veya Push Bildirim sırasında senin uygulama açık ve ön plandadır .

Yanıtlar:


152

iOS 10UNUserNotificationCenterDelegate , uygulamanız ön plandayken bildirimlerin işlenmesi için protokol ekler .

UNUserNotificationCenterDelegateProtokol bildirimi alma ve işlemleri işleme yöntemlerini tanımlamaktadır. Uygulamanız ön plandayken gelen bildirimler, sistem arayüzleri kullanılarak otomatik olarak görüntülenmek yerine temsilci nesnenize teslim edilir.

Swift:

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

Objective-C:

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

UNNotificationPresentationOptions bayrakları belirlemenize olanak tanır UNNotificationPresentationOptionAlertbildirimle sağlanan metni kullanarak bir uyarı görüntülemek için.

Bu, iOS 10 için yeni olan uygulamanız açıkken ve ön plandayken uyarıyı görüntülemenize izin verdiği için önemlidir .


Basit kod:

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)
    }
    
}

4
Uygulama arka planda olduğu gibi sistem tarafından gelen bir ön plan bildiriminin görüntülendiği bir çalışma kodu örneği sağlayabilir misiniz?
azmeuk

1
@azmeuk benim edin cevabı ...
chengsam

8
Eklemeyi unutmayın UNUserNotificationCenter.current().delegate = selfbölgesi application(_:willFinishLaunchingWithOptions:)veya application(_:didFinishLaunchingWithOptions:)yönteme
Deniss Fedotovs

3
Ayrıca, cihazınızı Rahatsız Etmeyin modunda olmadığından emin olun, aksi takdirde bildirimler Bildirim Merkezi'nde görünecek, ancak uygulamanızın üzerinde ön planda
sunulmayacaktır

2
benim 2 sentim: kaçırmayın: UserNotifications içe aktarın. !
ingconti

95

Uygulama ön plandayken başlık mesajını görüntülemek için aşağıdaki yöntemi kullanın.

iOS 10+, Swift 3+ :

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

1
Vay canına, okuduğum her yerde insanlar bunun mümkün olmadığını söyledi. Bu cevabı bulduğuma çok sevindim, tam olarak beklediğim gibi çalışıyor! Uygulama çalışırken, push bildirimleri artık tam olarak uygulama arka plandaysa olduğu gibi gösteriliyor. Teşekkür ederim!
Torre Lasley

1
Bu pasaj nereye gidiyor? AppDelegate'te mi yoksa başka bir yerde mi?
Yoav R.

@YoavR. AppDelegate
chengsam

Aynı kodu kullandım. Ancak uygulama ön plandayken bildirimin neden görüntülenmediğini bilmiyorum.
Boominadha Prakash M

3
Chengsam, bunu düzeltmek isteyebilirsiniz: Bunun AppDelegate. Uygun olan nesne için konulmalıdır UNUserNotificationCenterDelegate. Bununla birlikte, çoğu geliştiricinin AppDelegateuyum sağladığını söyledi UNUserNotificationCenterDelegate. @YoavR.
Bal

16

DÜZENLE:

Ön plan uyarıları artık iOS 10'da mümkün! Lütfen bu yanıta bakın .

İOS 9 ve altı için:

Uygulamanız açıkken ve ön plandayken hisse senedi iOS bildirim uyarısını göstermeniz mümkün görünmüyor. Messages.app özel bir API kullanıyor olmalıdır.

Sistem, uygulama zaten en öndeyken herhangi bir uyarı görüntülemez, uygulamanın simgesini işaretlemez veya herhangi bir ses çalmaz. - UILocalNotification belgeleri

UIApplicationDelegateYöntemler olacak hala yerel veya uzak bildirime yanıt verdiklerini uygulamanızı sağlayan çağrılabilir:

application:didReceiveLocalNotification:
application:didReceiveRemoteNotification:

Ancak, hisse senedi yerel iOS bildirim uyarı başlığı kullanıcı arabirimi, bir Özel API kullanması gereken Apple'ın Mesajlar.app'sinde olduğu gibi gösterilmeyecektir .

Yapabileceğiniz en iyi şey, kendi uyarı başlığınızı yuvarlamak veya mevcut bir çerçeve kullanmaktır:

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

Bu davranış için burada bir radar açtım: rdar://22313177


3
Peki whatsapp ve diğer ünlü uygulamalar bunu nasıl yapıyor?
Machado

@tardoandre'nin bir ekran görüntüsü var mı? Hisse senedi iOS uyarısını kendi görünümlerinde taklit ederek olduğunu varsayıyorum.
pkamb

2
toastAlertFromGithubBu üçüncü şahıs kitaplığının kullanılmasını öneriyorsanız , bağlantı eklemelisiniz !
Ketan Parmar

14

Uygulama açıkken bildirimleri göstermek için manuel olarak işlememiz gerekir. Bu yüzden aşağıda yaptığım şey, alınan bildirimi ele almaktır.

Aşağıdakilerin tümünü AppDelegate.m'ye ekleyin

  1. Bildirim için çağrıyı yönetin
  2. Bir görünüm oluşturun, AppIcon, Bildirim mesajı ekleyin ve bir animasyon olarak gösterin
  3. Dokunulduğunda kaldırmak için Dokunma tanıyıcı ekleyin veya animasyonla 5 saniye içinde kaldırın.

Bunun uygun bir çözüm olup olmadığını bana bildirin. Benim için iyi çalıştı ama doğru yol olup olmadığından emin değilim.

- (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) {


}];


}

3
Bu, kendi uyarınızı oluşturmak için iyi bir cevap olabilir, ancak ekran görüntüsünde gösterildiği gibi Stok iOS Uyarısını göstermiyor.
pkamb

Merhaba, nazik sözleriniz için teşekkür ederim. Evet, (eğer görünümden bahsediyorsanız), yukarıdaki resimde gösterilen iOS bildirimi ve kod yoluyla olanı özel olduğundan öyle görünmeyecektir. Belki görünümdeki görünümleri kopyalayabiliriz. WhatsApp'ın arka plan bulanıklığı vb.
İle

1
Biri olumsuz oy verdi :(. Nedenini duymak güzel olur!?. Teşekkürler.
Hafeez

2
Yaptım, çünkü bu yanıttaki kod (güzel olsa da) sorulan soruyu gerçekten cevaplamıyor: uygulamanın içinde bir stok iOS tost afişi gösteriliyor . SO'da bu cevabın harika olacağı başka sorular da var.
pkamb

1
Açıklığa kavuşturduğunuz için teşekkürler pkamb, mantıklı. Sanırım "hisse senedi" kelimesini kaçırdım.
Hafeez

10

Uygulama ön plandayken veya açık aşamadayken, iOS 10 ve Swift 2.3'te Anlık Bildirimi alacak kod.

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

UserInfo bildirimine erişmeniz gerekiyorsa kodu kullanın: notification.request.content.userInfo

Yöntem userNotificationCenter(_:willPresent:withCompletionHandler:)yalnızca, yüke özniteliği eklerseniz çağrılır content-available:1. Son yük şu şekilde olmalıdır:

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

1
userNotificationCenter(_:willPresent:withCompletionHandler:)uygulamanız ön planda çalışırken çağrılacaktır. Bu nedenle, " arka planda getirme " ile ilgili olan " içerik kullanılabilir " ile önemi YOKTUR .
DawnSong

9
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);
}];

Uygulama iOS 10 için etkin olduğunda anında bildirim gösterebilirim .

  1. Sunucudan gelen push bildirimi sessiz olmalıdır .

  2. Sunucudan uzak bildirim aldığınızda, yerel bir bildirim gönderir ve keyPath için değeri ayarlarsınız: shouldAlwaysAlertWhileAppIsForeground = True


hızlı 2'de - öyle, değil content.setValue("YES", forKeyPath: "shouldAlwaysAlertWhileAppIsForeground")mi? ("Evet" ile ve doğru değil)
Yoav R.

Dikkat: Bu, uygulamanızı iOS 12 altında
kilitler.

5

Bildirimi kendiniz halledebilir ve özel bir uyarı gösterebilirsiniz. Viber, Whatsapp ve BisPhone gibi uygulamalar bu yaklaşımı kullanır.

3. taraf özel uyarısına bir örnek CRToast'tır .

Uygulamanız ön plandayken yerel bir bildirim planlamayı deneyin; stok iOS uyarısının gösterilmediğini göreceksiniz:

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];
}

Teşekkürler, ancak hisse senedi iOS bildirim uyarısını kullanarak yanıtları arıyorum.
pkamb

1
tamam ama bunu yapamayacağınızı düşünüyorum, şu Bağlantıya da bakın: stackoverflow.com/questions/14872088/…
Mo Farhand

6
@matt Bu soruyu konuyla ilgili tutmaya çalışıyorum: stok iOS uyarısını ön planda gösteriyor. Diğer birçok "en iyi tost uyarısı çerçevesi" sorusu. "Ön planda Hayır, gösteremez iOS uyarı" bir cevap mükemmel kabul olurdu ve bu kadar ben bunun cevabını kabul edecek olan iOS'un gelecek sürümünde mümkün.
pkamb

4

Swift 3 versiyonu

Bu, uygulama ön plandayken bir uyarı gösterir.

if #available(iOS 10.0, *)
{
    // need to setup the global notification delegate somewhere when your app starts
    //
    UNUserNotificationCenter.current().delegate = applicationDelegate

    // to show a message
    //
    let content = UNMutableNotificationContent()
    content.body = "MESSAGE"

    let request = UNNotificationRequest(identifier: "fred", content: content, trigger: nil)
    UNUserNotificationCenter.current().add(request)
    {
       error in // called when message has been sent

       debugPrint("Error: \(error)")
    }
}

ApplicationDelegate'in uygulaması UNUserNotificationCenterDelegate

@available(iOS 10.0, *)
public func userNotificationCenter(_ center : UNUserNotificationCenter, willPresent notification : UNNotification, withCompletionHandler completionHandler : @escaping (UNNotificationPresentationOptions) -> Void)
{
    completionHandler([.alert]) // only-always show the alert
}

emin olmak için ... iOS 10'dan beri artık arka planda yaptığınız gibi uyarıları / afişleri / sesleri ön planda da gösterebileceğinizi mi kastediyorsunuz?
Honey

Yukarıdaki kodlama kısmını nereye koyabilirim? içinde RemoteNotification aldı mı?
user1960169

@Leslie Godwin, Ön Planda bildirimleri göstermek için ios 8.0 için çalışacak
Dilip Tiwari

2

Yerel Bildirimi göstermek için bu en iyi seçenektir. "BRYXBanner" https://cocoapods.org/pods/BRYXBanner'ı düzeltmek için daha az koda ihtiyacınız var

let banner = Banner(title: "title", subtitle: "subtitle", image: UIImage(named: "addContact"), backgroundColor: UIColor(red:137.0/255.0, green:172.0/255.0, blue:2.0/255.0, alpha:1.000))
    banner.dismissesOnTap = true
    banner.show(duration: 1.0)

Bu BRYXBannerçerçeve, hisse senedi iOS bildirim başlığını kullanmıyor gibi görünüyor .
pkamb

1

Dağıtım hedefiniz> = iOS10 ise, UNUserNotification'ı aşağıdaki gibi kullanın:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
    {
        // Change this to your preferred presentation option
        completionHandler([.alert, .sound])
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.