Azure Notification Hubs Zengin Anında İletme

Genel Bakış

Bir uygulama, kullanıcıların anında zengin içeriklerle etkileşim kurmasını sağlamak için düz metnin ötesine göndermek isteyebilir. Bu bildirimler kullanıcı etkileşimlerini teşvik eder ve URL'ler, sesler, görüntüler/kuponlar gibi daha fazlasını sunar. Bu öğretici , Kullanıcılara Bildirme öğreticisini temel alır ve yükleri (örneğin görüntüler) içeren anında iletme bildirimleri göndermeyi gösterir.

Bu öğretici iOS 7 ve 8 ile uyumludur.

Üç ekran görüntüsü: Anında İletme Gönder düğmesi olan bir uygulama ekranı, bir cihazda başlangıç ekranı ve Geri düğmesi olan bir Windows logosu.

Yüksek düzeyde:

  1. Uygulama arka ucu:
    • Zengin yükü (bu örnekte görüntü) arka uç veritabanında/yerel depolama alanında depolar.
    • Bu zengin bildirimin kimliğini cihaza gönderir.
  2. Cihazdaki uygulama:
    • Aldığı kimlikle zengin yükü isteyen arka uçla iletişim kurar.
    • Veri alma işlemi tamamlandığında cihaza kullanıcılara bildirim gönderir ve kullanıcılar daha fazla bilgi edinmek için dokunduğunda yükü hemen gösterir.

WebAPI projesi

  1. Visual Studio'da, Kullanıcılara Bildir öğreticisinde oluşturduğunuz AppBackend projesini açın.

  2. Kullanıcılara bildirmek istediğiniz görüntüyü alın ve proje dizininizdeki bir img klasörüne yerleştirin.

  3. Çözüm Gezgini Tüm Dosyaları Göster'e tıklayın ve Projeye Ekle klasörüne sağ tıklayın.

  4. Resim seçili durumdayken Özellikler penceresindeki Derleme EyleminiEklenmiş Kaynak olarak değiştirin.

    Çözüm Gezgini ekran görüntüsü. Görüntü dosyası seçilir ve Özellikler bölmesinde, eklenen kaynak derleme eylemi olarak listelenir.

  5. içine Notifications.csaşağıdaki using deyimi ekleyin:

    using System.Reflection;
    
  6. sınıfını Notifications aşağıdaki kodla değiştirin. Yer tutucuları bildirim hub'ı kimlik bilgileriniz ve görüntü dosyası adınızla değiştirmeyi unutmayın:

    public class Notification {
        public int Id { get; set; }
        // Initial notification message to display to users
        public string Message { get; set; }
        // Type of rich payload (developer-defined)
        public string RichType { get; set; }
        public string Payload { get; set; }
        public bool Read { get; set; }
    }
    
    public class Notifications {
        public static Notifications Instance = new Notifications();
    
        private List<Notification> notifications = new List<Notification>();
    
        public NotificationHubClient Hub { get; set; }
    
        private Notifications() {
            // Placeholders: replace with the connection string (with full access) for your notification hub and the hub name from the Azure Classics Portal
            Hub = NotificationHubClient.CreateClientFromConnectionString("{conn string with full access}",  "{hub name}");
        }
    
        public Notification CreateNotification(string message, string richType, string payload) {
            var notification = new Notification() {
                Id = notifications.Count,
                Message = message,
                RichType = richType,
                Payload = payload,
                Read = false
            };
    
            notifications.Add(notification);
    
            return notification;
        }
    
        public Stream ReadImage(int id) {
            var assembly = Assembly.GetExecutingAssembly();
            // Placeholder: image file name (for example, logo.png).
            return assembly.GetManifestResourceStream("AppBackend.img.{logo.png}");
        }
    }
    
  7. içinde NotificationsController.cs, aşağıdaki kodla yeniden tanımlayın NotificationsController . Bu, cihaza ilk sessiz zengin bildirim kimliğini gönderir ve görüntünün istemci tarafında alınmasına izin verir:

    // Return http response with image binary
    public HttpResponseMessage Get(int id) {
        var stream = Notifications.Instance.ReadImage(id);
    
        var result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new StreamContent(stream);
        // Switch in your image extension for "png"
        result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/{png}");
    
        return result;
    }
    
    // Create rich notification and send initial silent notification (containing id) to client
    public async Task<HttpResponseMessage> Post() {
        // Replace the placeholder with image file name
        var richNotificationInTheBackend = Notifications.Instance.CreateNotification("Check this image out!", "img",  "{logo.png}");
    
        var usernameTag = "username:" + HttpContext.Current.User.Identity.Name;
    
        // Silent notification with content available
        var aboutUser = "{\"aps\": {\"content-available\": 1, \"sound\":\"\"}, \"richId\": \"" + richNotificationInTheBackend.Id.ToString() + "\",  \"richMessage\": \"" + richNotificationInTheBackend.Message + "\", \"richType\": \"" + richNotificationInTheBackend.RichType + "\"}";
    
        // Send notification to apns
        await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(aboutUser, usernameTag);
    
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
  8. Şimdi bu uygulamayı tüm cihazlardan erişilebilir hale getirmek için bir Azure Web Sitesine yeniden dağıtın. AppBackend projesine sağ tıklayıp Yayımla’yı seçin.

  9. Yayımlama hedefiniz olarak Azure Web Sitesi'ne tıklayın. Azure hesabınızla oturum açın, var olan veya yeni bir Web Sitesi seçin ve Bağlantı sekmesinde hedef URL özelliğini not edin. Bu öğreticinin devamında bu URL'yi arka uç uç noktanız olarak adlandıracağız. Yayımla’yı seçin.

iOS projesini değiştirme

Uygulama arka ucunuzu yalnızca bir bildirimin kimliğini gönderecek şekilde değiştirdiğinize göre, iOS uygulamanızı bu kimliği işleyecek şekilde değiştirin ve arka ucunuzdan zengin iletiyi alın:

  1. iOS projenizi açın ve Hedefler bölümünde ana uygulama hedefinize giderek uzaktan bildirimleri etkinleştirin.

  2. Özellikler'i seçin, Arka Plan Modlarını etkinleştirin ve Uzak Bildirimler onay kutusunu işaretleyin.

    Özellikler ekranını gösteren iOS projesinin ekran görüntüsü. Arka Plan Modları açılır ve Uzak bildirimler onay kutusu seçilidir.

  3. öğesini açın Main.storyboardve Kullanıcıya Bildir öğreticisinden bir Görünüm Denetleyicisi (bu öğreticide Giriş Görünümü Denetleyicisi olarak adlandırılır) olduğundan emin olun.

  4. Görsel şeridinize bir Gezinti Denetleyicisi ekleyin ve Giriş Görünümü Denetleyicisi'ni gezintinin kök görünümü yapmak için control tuşuna basılı tutup sürükleyin. Yalnızca Gezinti Denetleyicisi için Öznitelikler denetçisindeki İlk Görünüm Denetleyicisi'nin seçili olduğundan emin olun.

  5. Görsel taslak için bir Görünüm Denetleyicisi ve bir Görüntü Görünümü ekleyin. Bu, kullanıcıların bildirime tıklayarak daha fazla bilgi edinmeyi seçtikten sonra göreceği sayfadır. Görsel taslak aşağıdaki gibi görünmelidir:

    Görsel taslak ekran görüntüsü. Üç uygulama ekranı görünür: gezinti görünümü, giriş görünümü ve görüntü görünümü.

  6. Görsel taslaktaki Giriş Görünümü Denetleyicisi'ne tıklayın ve Kimlik denetçisinin altında HomeViewController'ın Özel Sınıf ve Görsel Taslak Kimliği olduğundan emin olun.

  7. ImageViewController ile aynı işlemi Görüntü Görünümü Denetleyicisi için yapın.

  8. Ardından, yeni oluşturduğunuz kullanıcı arabirimini işlemek için imageViewController adlı yeni bir View Controller sınıfı oluşturun.

  9. imageViewController.h dosyasında, denetleyicinin arabirim bildirimlerine aşağıdaki kodu ekleyin. İki öğeyi bağlamak için görsel taslak görüntüsü görünümünden bu özelliklere control-drag işlemi yaptığınızdan emin olun:

    @property (weak, nonatomic) IBOutlet UIImageView *myImage;
    @property (strong) UIImage* imagePayload;
    
  10. içinde imageViewController.m, öğesinin sonuna viewDidloadaşağıdakileri ekleyin:

    // Display the UI Image in UI Image View
    [self.myImage setImage:self.imagePayload];
    
  11. içinde AppDelegate.m, oluşturduğunuz görüntü denetleyicisini içeri aktarın:

    #import "imageViewController.h"
    
  12. Aşağıdaki bildirime sahip bir arabirim bölümü ekleyin:

    @interface AppDelegate ()
    
    @property UIImage* imagePayload;
    @property NSDictionary* userInfo;
    @property BOOL iOS8;
    
    // Obtain content from backend with notification id
    - (void)retrieveRichImageWithId:(int)richId completion: (void(^)(NSError*)) completion;
    
    // Redirect to Image View Controller after notification interaction
    - (void)redirectToImageViewWithImage: (UIImage *)img;
    
    @end
    
  13. içinde AppDelegate, uygulamanızın içinde application: didFinishLaunchingWithOptionssessiz bildirimlere kaydoldığından emin olun:

    // Software version
    self.iOS8 = [[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)] && [[UIApplication sharedApplication] respondsToSelector:@selector(registerForRemoteNotifications)];
    
    // Register for remote notifications for iOS8 and previous versions
    if (self.iOS8) {
        NSLog(@"This device is running with iOS8.");
    
        // Action
        UIMutableUserNotificationAction *richPushAction = [[UIMutableUserNotificationAction alloc] init];
        richPushAction.identifier = @"richPushMore";
        richPushAction.activationMode = UIUserNotificationActivationModeForeground;
        richPushAction.authenticationRequired = NO;
        richPushAction.title = @"More";
    
        // Notification category
        UIMutableUserNotificationCategory* richPushCategory = [[UIMutableUserNotificationCategory alloc] init];
        richPushCategory.identifier = @"richPush";
        [richPushCategory setActions:@[richPushAction] forContext:UIUserNotificationActionContextDefault];
    
        // Notification categories
        NSSet* richPushCategories = [NSSet setWithObjects:richPushCategory, nil];
    
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound |
                                                UIUserNotificationTypeAlert |
                                                UIUserNotificationTypeBadge
                                                                                    categories:richPushCategories];
    
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    
    }
    else {
        // Previous iOS versions
        NSLog(@"This device is running with iOS7 or earlier versions.");
    
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability];
    }
    
    return YES;
    
  14. Görsel taslak kullanıcı arabirimi değişikliklerini hesaba katmak için application:didRegisterForRemoteNotificationsWithDeviceToken aşağıdaki uygulamasını yerine kullanın:

    // Access navigation controller which is at the root of window
    UINavigationController *nc = (UINavigationController *)self.window.rootViewController;
    // Get home view controller from stack on navigation controller
    homeViewController *hvc = (homeViewController *)[nc.viewControllers objectAtIndex:0];
    hvc.deviceToken = deviceToken;
    
  15. Ardından, uç noktanızdan görüntüyü almak ve alma tamamlandığında yerel bir bildirim göndermek için aşağıdaki yöntemleri AppDelegate.m ekleyin. Yer tutucuyu {backend endpoint} arka uç uç noktanızla değiştirdiğinden emin olun:

    NSString *const GetNotificationEndpoint = @"{backend endpoint}/api/notifications";
    
    // Helper: retrieve notification content from backend with rich notification id
    - (void)retrieveRichImageWithId:(int)richId completion: (void(^)(NSError*)) completion {
        UINavigationController *nc = (UINavigationController *)self.window.rootViewController;
        homeViewController *hvc = (homeViewController *)[nc.viewControllers objectAtIndex:0];
        NSString* authenticationHeader = hvc.registerClient.authenticationHeader;
        // Check if authenticated
        if (!authenticationHeader) return;
    
        NSURLSession* session = [NSURLSession
                                sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                delegate:nil
                                delegateQueue:nil];
    
        NSURL* requestURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%d", GetNotificationEndpoint, richId]];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL];
        [request setHTTPMethod:@"GET"];
        NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@", authenticationHeader];
        [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"];
    
        NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
            if (!error && httpResponse.statusCode == 200) {
                // From NSData to UIImage
                self.imagePayload = [UIImage imageWithData:data];
    
                completion(nil);
            }
            else {
                NSLog(@"Error status: %ld, request: %@", (long)httpResponse.statusCode, error);
                if (error)
                    completion(error);
                else {
                    completion([NSError errorWithDomain:@"APICall" code:httpResponse.statusCode userInfo:nil]);
                }
            }
        }];
        [dataTask resume];
    }
    
    // Handle silent push notifications when id is sent from backend
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler {
        self.userInfo = userInfo;
        int richId = [[self.userInfo objectForKey:@"richId"] intValue];
        NSString* richType = [self.userInfo objectForKey:@"richType"];
    
        // Retrieve image data
        if ([richType isEqualToString:@"img"]) {  
            [self retrieveRichImageWithId:richId completion:^(NSError* error) {
                if (!error){
                    // Send local notification
                    UILocalNotification* localNotification = [[UILocalNotification alloc] init];
    
                    // "5" is arbitrary here to give you enough time to quit out of the app and receive push notifications
                    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
                    localNotification.userInfo = self.userInfo;
                    localNotification.alertBody = [self.userInfo objectForKey:@"richMessage"];
                    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    
                    // iOS8 categories
                    if (self.iOS8) {
                        localNotification.category = @"richPush";
                    }
    
                    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    
                    handler(UIBackgroundFetchResultNewData);
                }
                else{
                    handler(UIBackgroundFetchResultFailed);
                }
            }];
        }
        // Add "else if" here to handle more types of rich content such as url, sound files, etc.
    }
    
  16. Görüntü görünümü denetleyicisini AppDelegate.m içinde aşağıdaki yöntemlerle açarak önceki yerel bildirimi işleyebilirsiniz:

    // Helper: redirect users to image view controller
    - (void)redirectToImageViewWithImage: (UIImage *)img {
        UINavigationController *navigationController = (UINavigationController*) self.window.rootViewController;
        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
        imageViewController *imgViewController = [mainStoryboard instantiateViewControllerWithIdentifier: @"imageViewController"];
        // Pass data/image to image view controller
        imgViewController.imagePayload = img;
    
        // Redirect
        [navigationController pushViewController:imgViewController animated:YES];
    }
    
    // Handle local notification sent above in didReceiveRemoteNotification
    - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
        if (application.applicationState == UIApplicationStateActive) {
            // Show in-app alert with an extra "more" button
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Notification" message:notification.alertBody delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"More", nil];
            [alert show];
        }
        // App becomes active from user's tap on notification
        else {
            [self redirectToImageViewWithImage:self.imagePayload];
        }
    }
    
    // Handle buttons in in-app alerts and redirect with data/image
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
        // Handle "more" button
        if (buttonIndex == 1)
        {
            [self redirectToImageViewWithImage:self.imagePayload];
        }
        // Add "else if" here to handle more buttons
    }
    
    // Handle notification setting actions in iOS8
    - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler {
        // Handle richPush related buttons
        if ([identifier isEqualToString:@"richPushMore"]) {
            [self redirectToImageViewWithImage:self.imagePayload];
        }
        completionHandler();
    }
    

Uygulamayı Çalıştırma

  1. XCode'da uygulamayı fiziksel bir iOS cihazında çalıştırın (anında iletme bildirimleri simülatörde çalışmaz).
  2. iOS uygulama kullanıcı arabiriminde, kimlik doğrulaması için aynı değere sahip bir kullanıcı adı ve parola girin ve Oturum Aç'a tıklayın.
  3. Gönderme gönder'e tıkladığınızda bir uygulama içi uyarı görmeniz gerekir. Diğer'e tıklarsanız, uygulamanızın arka ucuna eklemeyi seçtiğiniz görüntüye gelirsiniz.
  4. Ayrıca Anında iletme gönder'e tıklayabilir ve cihazınızın giriş düğmesine hemen basabilirsiniz. Birkaç dakika içinde bir anında iletme bildirimi alacaksınız. Buna dokunursanız veya Diğer'e tıklarsanız, uygulamanıza ve zengin görüntü içeriğine getirilirsiniz.