다음을 통해 공유


자습서: Azure Notification Hubs를 사용하여 특정 iOS 디바이스에 푸시 알림 보내기

개요

이 자습서에서는 Azure Notification Hubs를 사용하여 iOS 앱에 속보 알림을 브로드캐스트하는 방법을 보여 줍니다. 완료되면 관심 있는 속보 범주에 등록하고 해당 범주에 대한 푸시 알림만 받을 수 있습니다. 이 시나리오는 이전에 관심을 선언한 사용자 그룹(예: RSS 판독기, 음악 팬용 앱 등)으로 알림을 보내야 하는 많은 앱의 일반적인 패턴입니다.

브로드캐스트 시나리오는 알림 허브에서 등록을 만들 때 하나 이상의 태그 를 포함하여 활성화됩니다. 알림이 태그로 전송되면 태그에 등록된 디바이스는 알림을 받습니다. 태그는 단순히 문자열이므로 미리 프로비전할 필요가 없습니다. 태그에 대한 자세한 내용은 Notification Hubs 라우팅 및 태그 식을 참조하세요.

이 자습서에서는 다음 단계를 수행합니다.

  • 앱에 범주 선택 항목 추가
  • 태그가 지정된 알림 보내기
  • 디바이스에서 알림 보내기
  • 앱 실행 및 알림 생성

필수 조건

이 항목은 자습서: Azure Notification Hubs를 사용하여 iOS 앱에 알림 푸시에서 만든 앱을 기반으로 합니다. 이 자습서를 시작하기 전에 Azure Notification Hubs를 사용하여 iOS 앱에 알림 푸시 자습서를 이미 완료해야 합니다.

앱에 범주 선택 추가

첫 번째 단계는 사용자가 등록할 범주를 선택할 수 있도록 기존 스토리보드에 UI 요소를 추가하는 것입니다. 사용자가 선택한 범주는 디바이스에 저장됩니다. 앱이 시작되면 선택한 범주를 태그로 사용하여 알림 허브에 디바이스 등록이 만들어집니다.

  1. MainStoryboard_iPhone.storyboard에서 개체 라이브러리에서 다음 구성 요소를 추가합니다.

    • 속보라는 텍스트가 있는 레이블.

    • 레이블에는 범주 텍스트 세계, 정치, 비즈니스, 기술, 과학스포츠가 포함됩니다.

    • 범주당 하나씩 6개의 스위치는 각 스위치 상태를 기본적으로 해제 로 설정합니다.

    • 구독 레이블이 지정된 단추 하나.

      스토리보드는 다음과 같이 표시됩니다.

      Xcode 인터페이스 작성기

  2. 보조 편집기에서 모든 스위치에 대한 콘센트를 만들고 WorldSwitch, PoliticsSwitch, BusinessSwitch, TechnologySwitch, ScienceSwitchSportsSwitch라고 부릅니다.

  3. 버튼 subscribe에 대한 작업을 생성하고, ViewController.h에 다음 코드를 포함해야 합니다.

    @property (weak, nonatomic) IBOutlet UISwitch *WorldSwitch;
    @property (weak, nonatomic) IBOutlet UISwitch *PoliticsSwitch;
    @property (weak, nonatomic) IBOutlet UISwitch *BusinessSwitch;
    @property (weak, nonatomic) IBOutlet UISwitch *TechnologySwitch;
    @property (weak, nonatomic) IBOutlet UISwitch *ScienceSwitch;
    @property (weak, nonatomic) IBOutlet UISwitch *SportsSwitch;
    
    - (IBAction)subscribe:(id)sender;
    
  4. Cocoa Touch 클래스Notifications 만듭니다. Notifications.h 파일의 인터페이스 섹션에서 다음 코드를 복사합니다.

    @property NSData* deviceToken;
    
    - (id)initWithConnectionString:(NSString*)listenConnectionString HubName:(NSString*)hubName;
    
    - (void)storeCategoriesAndSubscribeWithCategories:(NSArray*)categories
                completion:(void (^)(NSError* error))completion;
    
    - (NSSet*)retrieveCategories;
    
    - (void)subscribeWithCategories:(NSSet*)categories completion:(void (^)(NSError *))completion;
    
  5. Notifications.m에 다음 가져오기 지시문을 추가합니다.

    #import <WindowsAzureMessaging/WindowsAzureMessaging.h>
    
  6. Notifications.m 파일의 구현 섹션에서 다음 코드를 복사합니다.

    SBNotificationHub* hub;
    
    - (id)initWithConnectionString:(NSString*)listenConnectionString HubName:(NSString*)hubName{
    
        hub = [[SBNotificationHub alloc] initWithConnectionString:listenConnectionString
                                    notificationHubPath:hubName];
    
        return self;
    }
    
    - (void)storeCategoriesAndSubscribeWithCategories:(NSSet *)categories completion:(void (^)(NSError *))completion {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
        [defaults setValue:[categories allObjects] forKey:@"BreakingNewsCategories"];
    
        [self subscribeWithCategories:categories completion:completion];
    }
    
    - (NSSet*)retrieveCategories {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        NSArray* categories = [defaults stringArrayForKey:@"BreakingNewsCategories"];
    
        if (!categories) return [[NSSet alloc] init];
        return [[NSSet alloc] initWithArray:categories];
    }
    
    - (void)subscribeWithCategories:(NSSet *)categories completion:(void (^)(NSError *))completion
    {
        NSString* templateBodyAPNS = @"{\"aps\":{\"alert\":\"$(messageParam)\"}}";
    
        [hub registerTemplateWithDeviceToken:self.deviceToken name:@"simpleAPNSTemplate" 
            jsonBodyTemplate:templateBodyAPNS expiryTemplate:@"0" tags:categories completion:completion];
    }
    

    이 클래스는 로컬 스토리지를 사용하여 이 디바이스가 수신하는 뉴스 범주를 저장하고 검색합니다. 또한 템플릿 등록을 사용하여 이러한 범주에 등록하는 메서드를 포함합니다.

  7. AppDelegate.h 파일에서 Notifications.h에 대한 import 문을 추가하고, Notifications 클래스의 인스턴스에 대한 속성을 추가합니다.

    #import "Notifications.h"
    
    @property (nonatomic) Notifications* notifications;
    
  8. 메서드에서 didFinishLaunchingWithOptionsAppDelegate.m메서드의 시작 부분에 알림 인스턴스를 초기화하는 코드를 추가합니다.
    HUBNAMEHUBLISTENACCESS(hubinfo.h에 정의됨)는 <hub name><connection string with listen access> 자리 표시자를 알림 허브 이름과 앞서 얻었던 DefaultListenSharedAccessSignature의 연결 문자열로 바꿉니다.

    self.notifications = [[Notifications alloc] initWithConnectionString:HUBLISTENACCESS HubName:HUBNAME];
    

    비고

    클라이언트 앱과 함께 배포된 자격 증명은 일반적으로 안전하지 않으므로 클라이언트 앱으로 수신 대기 액세스를 위한 키만 배포해야 합니다. 수신 대기 액세스를 사용하면 앱에서 알림을 등록할 수 있지만 기존 등록은 수정할 수 없으며 알림을 보낼 수 없습니다. 전체 액세스 키는 알림을 보내고 기존 등록을 변경하기 위해 보안 백 엔드 서비스에서 사용됩니다.

  9. didRegisterForRemoteNotificationsWithDeviceToken 메서드에서 AppDelegate.m 메서드의 코드를 다음 코드로 바꿔서 디바이스 토큰을 notifications 클래스에 전달합니다. 클래스는 notifications 범주를 사용하여 알림에 대한 등록을 수행합니다. 사용자가 범주 선택을 변경하는 경우 subscribeWithCategories 단추에 대한 응답으로 메서드를 호출 하여 업데이트합니다.

    비고

    APNS(Apple Push Notification Service)에서 할당한 디바이스 토큰은 언제든지 변경할 수 있으므로 알림 오류를 방지하기 위해 알림을 자주 등록해야 합니다. 이 예제에서는 앱이 시작될 때마다 알림을 등록합니다. 하루에 두 번 이상 자주 실행되는 앱의 경우 이전 등록 이후 하루도 채 지나지 않은 경우 대역폭을 유지하기 위해 등록을 건너뛸 수 있습니다.

    self.notifications.deviceToken = deviceToken;
    
    // Retrieves the categories from local storage and requests a registration for these categories
    // each time the app starts and performs a registration.
    
    NSSet* categories = [self.notifications retrieveCategories];
    [self.notifications subscribeWithCategories:categories completion:^(NSError* error) {
        if (error != nil) {
            NSLog(@"Error registering for notifications: %@", error);
        }
    }];
    

    이때 메서드에 다른 코드가 didRegisterForRemoteNotificationsWithDeviceToken 없어야 합니다.

  10. AppDelegate.m에서 Notification Hubs 시작 자습서를 완료하면 다음 메서드가 이미 존재해야 합니다. 그렇지 않은 경우 추가합니다.

    - (void)MessageBox:(NSString *)title message:(NSString *)messageText
    {
    
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:messageText delegate:self
            cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:
       (NSDictionary *)userInfo {
       NSLog(@"%@", userInfo);
       [self MessageBox:@"Notification" message:[[userInfo objectForKey:@"aps"] valueForKey:@"alert"]];
     }
    

    이 메서드는 간단한 UIAlert를 표시하여 앱이 실행 중일 때 수신되는 알림을 처리합니다.

  11. ViewController.m에 대한 importAppDelegate.h 문을 추가하고, 다음 코드를 XCode가 생성한 subscribe 메서드에 복사합니다. 이 코드는 사용자가 사용자 인터페이스에서 선택한 새 범주 태그를 사용하도록 알림 등록을 업데이트합니다.

    #import "Notifications.h"
    
    NSMutableArray* categories = [[NSMutableArray alloc] init];
    
    if (self.WorldSwitch.isOn) [categories addObject:@"World"];
    if (self.PoliticsSwitch.isOn) [categories addObject:@"Politics"];
    if (self.BusinessSwitch.isOn) [categories addObject:@"Business"];
    if (self.TechnologySwitch.isOn) [categories addObject:@"Technology"];
    if (self.ScienceSwitch.isOn) [categories addObject:@"Science"];
    if (self.SportsSwitch.isOn) [categories addObject:@"Sports"];
    
    Notifications* notifications = [(AppDelegate*)[[UIApplication sharedApplication]delegate] notifications];
    
    [notifications storeCategoriesAndSubscribeWithCategories:categories completion: ^(NSError* error) {
        if (!error) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:"Notification" message:"Subscribed" delegate:self
            cancelButtonTitle:@"OK" otherButtonTitles: nil];
            [alert show];
        } else {
            NSLog(@"Error subscribing: %@", error);
        }
    }];
    

    이 메서드는 범주를 NSMutableArray 만들고 클래스를 Notifications 사용하여 목록을 로컬 스토리지에 저장하고 해당 태그를 알림 허브에 등록합니다. 범주가 변경되면 등록이 새 범주로 다시 만들어집니다.

  12. 에서 ViewController.m메서드에 viewDidLoad 다음 코드를 추가하여 이전에 저장된 범주에 따라 사용자 인터페이스를 설정합니다.

    // This updates the UI on startup based on the status of previously saved categories.
    
    Notifications* notifications = [(AppDelegate*)[[UIApplication sharedApplication]delegate] notifications];
    
    NSSet* categories = [notifications retrieveCategories];
    
    if ([categories containsObject:@"World"]) self.WorldSwitch.on = true;
    if ([categories containsObject:@"Politics"]) self.PoliticsSwitch.on = true;
    if ([categories containsObject:@"Business"]) self.BusinessSwitch.on = true;
    if ([categories containsObject:@"Technology"]) self.TechnologySwitch.on = true;
    if ([categories containsObject:@"Science"]) self.ScienceSwitch.on = true;
    if ([categories containsObject:@"Sports"]) self.SportsSwitch.on = true;
    

이제 앱은 앱이 시작될 때마다 알림 허브에 등록하는 데 사용되는 디바이스 로컬 스토리지에 범주 집합을 저장할 수 있습니다. 사용자는 런타임에 범주 선택을 변경하고 메서드를 subscribe 클릭하여 디바이스에 대한 등록을 업데이트할 수 있습니다. 다음으로, 앱 자체에서 바로 속보 알림을 보내도록 앱을 업데이트합니다.

(선택 사항) 태그가 지정된 알림 보내기

Visual Studio에 액세스할 수 없는 경우 다음 섹션으로 건너뛰고 앱 자체에서 알림을 보낼 수 있습니다. 알림 허브에 대한 디버그 탭을 사용하여 Azure Portal 에서 적절한 템플릿 알림을 보낼 수도 있습니다.

이 섹션에서는 .NET 콘솔 앱에서 태그가 지정된 템플릿 알림으로 속보를 보냅니다.

  1. Visual Studio에서 새 Visual C# 콘솔 애플리케이션을 만듭니다.

    1. 메뉴에서>파일>프로젝트를 선택합니다.
    2. 새 프로젝트 만들기의 템플릿 목록에서 C#용 콘솔 앱(.NET Framework)을 선택하고 다음을 선택합니다.
    3. 앱의 이름을 입력합니다.
    4. 솔루션의 경우 솔루션에 추가를 선택하고 만들기를 선택하여 프로젝트를 만듭니다.
  2. 도구>NuGet 패키지 관리자>패키지 관리자 콘솔을 선택한 다음 콘솔 창에서 다음 명령을 실행합니다.

    Install-Package Microsoft.Azure.NotificationHubs
    

    이 작업은 Microsoft.Azure.NotificationHubs 패키지를 사용하여 Azure Notification Hubs SDK에 대한 참조를 추가합니다.

  3. Program.cs 파일을 열고 다음 using 문을 추가합니다.

    using Microsoft.Azure.NotificationHubs;
    
  4. 클래스에서 Program 다음 메서드를 추가하거나 이미 있는 경우 바꿉니다.

    private static async void SendTemplateNotificationAsync()
    {
        // Define the notification hub.
        NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<connection string with full access>", "<hub name>");
    
        // Apple requires the apns-push-type header for all requests
        var headers = new Dictionary<string, string> {{"apns-push-type", "alert"}};
    
        // Create an array of breaking news categories.
        var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"};
    
        // Send the notification as a template notification. All template registrations that contain
        // "messageParam" and the proper tags will receive the notifications.
        // This includes APNS, GCM/FCM, WNS, and MPNS template registrations.
    
        Dictionary<string, string> templateParams = new Dictionary<string, string>();
    
        foreach (var category in categories)
        {
            templateParams["messageParam"] = "Breaking " + category + " News!";
            await hub.SendTemplateNotificationAsync(templateParams, category);
        }
    }
    

    이 코드는 문자열 배열의 6개 태그 각각에 대한 템플릿 알림을 보냅니다. 태그를 사용하면 디바이스가 등록된 범주에 대해서만 알림을 받을 수 있습니다.

  5. 위의 코드에서 <hub name><connection string with full access> 자리 표시자를 각각 알림 허브 이름과 대시보드에서 가져온 DefaultFullSharedAccessSignature 연결 문자열로 바꾸세요.

  6. 메서드에서 Main() 다음 줄을 추가합니다.

     SendTemplateNotificationAsync();
     Console.ReadLine();
    
  7. 콘솔 앱을 빌드합니다.

(선택 사항) 디바이스에서 알림 보내기

일반적으로 알림은 백 엔드 서비스에서 전송되지만 앱에서 직접 속보 알림을 보낼 수 있습니다. 이렇게 하려면 SendNotificationRESTAPI 자습서에서 정의한 메서드를 업데이트합니다.

  1. 범주 ViewController.m태그에 SendNotificationRESTAPI 대한 매개 변수를 수락하고 적절한 템플릿 알림을 보내도록 메서드를 다음과 같이 업데이트합니다.

    - (void)SendNotificationRESTAPI:(NSString*)categoryTag
    {
        NSURLSession* session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration
                                    defaultSessionConfiguration] delegate:nil delegateQueue:nil];
    
        NSString *json;
    
        // Construct the messages REST endpoint
        NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@/messages/%@", HubEndpoint,
                                            HUBNAME, API_VERSION]];
    
        // Generated the token to be used in the authorization header.
        NSString* authorizationToken = [self generateSasToken:[url absoluteString]];
    
        //Create the request to add the template notification message to the hub
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        [request setHTTPMethod:@"POST"];
    
        // Add the category as a tag
        [request setValue:categoryTag forHTTPHeaderField:@"ServiceBusNotification-Tags"];
    
        // Template notification
        json = [NSString stringWithFormat:@"{\"messageParam\":\"Breaking %@ News : %@\"}",
                categoryTag, self.notificationMessage.text];
    
        // Signify template notification format
        [request setValue:@"template" forHTTPHeaderField:@"ServiceBusNotification-Format"];
    
        // JSON Content-Type
        [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    
        //Authenticate the notification message POST request with the SaS token
        [request setValue:authorizationToken forHTTPHeaderField:@"Authorization"];
    
        //Add the notification message body
        [request setHTTPBody:[json dataUsingEncoding:NSUTF8StringEncoding]];
    
        // Send the REST request
        NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
                    completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
            {
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
                if (error || httpResponse.statusCode != 200)
                {
                    NSLog(@"\nError status: %d\nError: %@", httpResponse.statusCode, error);
                }
                if (data != NULL)
                {
                    //xmlParser = [[NSXMLParser alloc] initWithData:data];
                    //[xmlParser setDelegate:self];
                    //[xmlParser parse];
                }
            }];
    
        [dataTask resume];
    }
    
  2. ViewController.m에서, 뒤이어 나오는 코드에 표시된 대로 Send Notification 작업을 업데이트합니다. 따라서 각 태그를 사용하여 알림을 개별적으로 보내고 여러 플랫폼으로 보냅니다.

    - (IBAction)SendNotificationMessage:(id)sender
    {
        self.sendResults.text = @"";
    
        NSArray* categories = [NSArray arrayWithObjects: @"World", @"Politics", @"Business",
                                @"Technology", @"Science", @"Sports", nil];
    
        // Lets send the message as breaking news for each category to WNS, FCM, and APNS
        // using a template.
        for(NSString* category in categories)
        {
            [self SendNotificationRESTAPI:category];
        }
    }
    
  3. 프로젝트를 다시 빌드하고 빌드 오류가 없는지 확인합니다.

앱 실행 및 알림 생성

  1. 실행 단추를 눌러 프로젝트를 빌드하고 앱을 시작합니다. 구독할 몇 가지 속보 옵션을 선택한 다음 구독 단추를 누릅니다. 알림이 구독되었음을 나타내는 대화 상자가 표시됩니다.

    iOS의 알림 예제

    구독을 선택하면 앱은 선택한 범주를 태그로 변환하고 알림 허브에서 선택한 태그에 대한 새 디바이스 등록을 요청합니다.

  2. 속보로 보낼 메시지를 입력한 다음 알림 보내기 단추를 누릅니다. 또는 .NET 콘솔 앱을 실행하여 알림을 생성합니다.

    iOS에서 알림 기본 설정 변경

  3. 속보를 구독하는 각 디바이스는 방금 보낸 속보 알림을 받습니다.

다음 단계

이 자습서에서는 범주에 등록된 특정 iOS 디바이스에 브로드캐스트 알림을 보냈습니다. 지역화된 알림을 푸시하는 방법을 알아보려면 다음 자습서로 진행합니다.