2016-09-24 10 views
8

iOS 10でメディアを追加したいが、プッシュ通知が表示されますが、画像はプッシュでは機能しません。どのようにObjective-Cでそれを行うには?iOS 10リッチメディアプッシュ通知(Media Attachment)をObjective-Cで

AppDelegate.h

#import <UIKit/UIKit.h> 
#import <CoreLocation/CoreLocation.h> 
#import <UserNotifications/UserNotifications.h> 

@interface AppDelegate : UIResponder <UIApplicationDelegate,CLLocationManagerDelegate,UNUserNotificationCenterDelegate> 

@property (strong, nonatomic) UIWindow *window; 
@end 

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    if(SYSTEM_VERSION_LESS_THAN(@"10.0")) { 
     [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; 
     [[UIApplication sharedApplication] registerForRemoteNotifications]; 
    } else{ 
     UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; 
     center.delegate = self; 
     [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) 
     { 
      if(!error) { 
       [[UIApplication sharedApplication] registerForRemoteNotifications]; 
       // required to get the app to do anything at all about push notifications 
       NSLog(@"Push registration success."); 
      } else { 
       NSLog(@"Push registration FAILED"); 
       NSLog(@"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription); 
       NSLog(@"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion); 
      } 
     }]; 
    } 
} 

-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
    NSString * token = [NSString stringWithFormat:@"%@", deviceToken]; 
    //Format token as per need: 
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; 
    token = [token stringByReplacingOccurrencesOfString:@">" withString:@""]; 
    token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""]; 
    NSLog(@"Device Token is \n%@",token); 
} 

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 
{ 
    NSLog(@"Error:%@",error); 
} 

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { 
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) { 
     [self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result){}]; 
    } else { 
     /// previous stuffs for iOS 9 and below. I've shown an alert wth received data. 
    } 
} 

-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void(^)(UIBackgroundFetchResult))completionHandler { 
    // iOS 10 will handle notifications through other methods 

    if(NOTIFY_VISITORS_SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) 
    { 
     NSLog(@"iOS version >= 10. Let NotificationCenter handle this one."); 
     // set a member variable to tell the new delegate that this is background 
     return; 
    } 
    NSLog(@"HANDLE PUSH, didReceiveRemoteNotification: %@", userInfo); 
    // custom code to handle notification content 
    if([UIApplication sharedApplication].applicationState == UIApplicationStateInactive) 
    { 
     NSLog(@"INACTIVE"); 
     completionHandler(UIBackgroundFetchResultNewData); 
    } 
    else if([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) 
    { 
     NSLog(@"BACKGROUND"); 
     completionHandler(UIBackgroundFetchResultNewData); 
    } 
    else 
    { 
     NSLog(@"FOREGROUND"); 
     completionHandler(UIBackgroundFetchResultNewData); 
    } 
} 

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { 
    NSLog(@"Handle push from foreground"); 
    // custom code to handle push while app is in the foreground 
    NSLog(@"%@", notification.request.content.userInfo); 
} 

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { 
    NSLog(@"Handle push from background or closed"); 
    // if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background 
    NSLog(@"%@", response.notification.request.content.userInfo); 

は、その後、私は次のように新しいターゲット通知サービス拡張を追加しました:次のように私のコードは次のようになります。

#import <UserNotifications/UserNotifications.h> 
@interface NotificationService : UNNotificationServiceExtension 
@end 

NotificationService.m

#import "NotificationService.h" 

@interface NotificationService() 

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); 
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; 

@end 

@implementation NotificationService 

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { 
    self.contentHandler = contentHandler; 
    self.bestAttemptContent = [request.content mutableCopy]; 

    // Modify the notification content here... 
    //self.bestAttemptContent.body = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.body]; 

    // check for media attachment, example here uses custom payload keys mediaUrl and mediaType 
    NSDictionary *userInfo = request.content.userInfo; 
    if (userInfo == nil) { 
     [self contentComplete]; 
     return; 
    } 

    NSString *mediaUrl = userInfo[@"mediaUrl"]; 
    NSString *mediaType = userInfo[@"mediaType"]; 

    if (mediaUrl == nil || mediaType == nil) { 
     [self contentComplete]; 
     return; 
    } 

    // load the attachment 
    [self loadAttachmentForUrlString:mediaUrl 
          withType:mediaType 
        completionHandler:^(UNNotificationAttachment *attachment) { 
         if (attachment) { 
          self.bestAttemptContent.attachments = [NSArray arrayWithObject:attachment]; 
         } 
         [self contentComplete]; 
        }]; 

} 

- (void)serviceExtensionTimeWillExpire { 
    // Called just before the extension will be terminated by the system. 
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. 
    [self contentComplete]; 
} 

- (void)contentComplete { 
    self.contentHandler(self.bestAttemptContent); 
} 

- (NSString *)fileExtensionForMediaType:(NSString *)type { 
    NSString *ext = type; 

    if ([type isEqualToString:@"image"]) { 
     ext = @"jpg"; 
    } 

    if ([type isEqualToString:@"video"]) { 
     ext = @"mp4"; 
    } 

    if ([type isEqualToString:@"audio"]) { 
     ext = @"mp3"; 
    } 

    return [@"." stringByAppendingString:ext]; 
} 

- (void)loadAttachmentForUrlString:(NSString *)urlString withType:(NSString *)type completionHandler:(void(^)(UNNotificationAttachment *))completionHandler { 

    __block UNNotificationAttachment *attachment = nil; 
    NSURL *attachmentURL = [NSURL URLWithString:urlString]; 
    NSString *fileExt = [self fileExtensionForMediaType:type]; 

    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 
    [[session downloadTaskWithURL:attachmentURL 
       completionHandler:^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) { 
        if (error != nil) { 
         NSLog(@"%@", error.localizedDescription); 
        } else { 
         NSFileManager *fileManager = [NSFileManager defaultManager]; 
         NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path stringByAppendingString:fileExt]]; 
         [fileManager moveItemAtURL:temporaryFileLocation toURL:localURL error:&error]; 

         NSError *attachmentError = nil; 
         attachment = [UNNotificationAttachment attachmentWithIdentifier:@"" URL:localURL options:nil error:&attachmentError]; 
         if (attachmentError) { 
         NSLog(@"%@", attachmentError.localizedDescription); 
         } 
        } 
        completionHandler(attachment); 
       }] resume]; 
} 
@end 

と私の通知サービス拡張のInfo.plist NotificationService.hは次のとおりです。 Notification Service Extension Info.plist

そして私はにPHPスクリプトを使用していますプッシュ通知を次のように送信します。

TestPush.php

<?php 

// Put your device token here (without spaces): 
    $deviceToken = 'my device tocken goes here'; 
// Put your private key's passphrase here: 
$passphrase = 'mypassphase'; 
// Put your alert message here: 
$message = 'Test iOS 10 Media Attachment Push'; 

//////////////////////////////////////////////////////////////////////////////// 

$ctx = stream_context_create(); 
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem'); 
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); 
stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer'); 

// Open a connection to the APNS server 
$fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err, 
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); 

if (!$fp) 
    exit("Failed to connect: $err $errstr" . PHP_EOL); 

echo 'Connected to APNS' . PHP_EOL; 

// Create the payload body 
$body['aps'] = array(
    'alert' => $message, 
    'sound' => 'default', 
    'mutable-content' => 1, 
    'category'=> "pusher" 
    ); 
$body['data'] = array(
    'mediaUrl' => "http://www.alphansotech.com/wp-content/uploads/2015/12/Push-notification-1.jpg", 
    'mediaType' => "jpg" 
); 
// Encode the payload as JSON 
$payload = json_encode($body); 

// Build the binary notification 
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload; 

// Send it to the server 
$result = fwrite($fp, $msg, strlen($msg)); 

if (!$result) 
    echo 'Message not delivered' . PHP_EOL; 
else 
    echo 'Message successfully delivered' . PHP_EOL; 

// Close the connection to the server 
fclose($fp); 

共有画像やファイルは、それを示すために、そのリンクを送信するサーバとpuah上でホストされています。

誰でも助けてください。

+0

こんにちは私はObjective-Cでもこれを実装しようとしていますが、オンラインではリソースを見つけることはできません...あなたのコードやリンクをあなたが使ったリソースに共有できますか?ありがとう! – SJTriggs

+0

上記のコードはうまく動作していますが、オーディオとビデオだけで動作しません。ペイロードフォーマットを変更するだけで、[この質問]の1番目の答えを参照してください(http://stackoverflow.com/questions/39673707/ios-10-rich-media-push-notification-media-attachment-in-objective-c ?noredirect = 1#comment67813533_39673707)また、オーディオとビデオをサポートするための解決策が見つかった場合は、その解決策も参照してください。 –

+0

私は上記のコードとペイロードを実装していますが、完全には機能していません。スクリーンショットにキー名が表示されないため、info.plistと何か関係があると思います。 ' NSExtension \t NSExtensionAttributes \t \t \t \t \t UNNotificationExtensionCategory \t \t \t : – SJTriggs

答えて

4

あなたのコードは大丈夫です、それだけで別のプッシュ通知データ形式を想定していますと

// Create the payload body 
$body['aps'] = array(
    'alert' => $message, 
    'sound' => 'default', 
    'mutable-content' => 1, 
    'category'=> "pusher" 
    ); 
$body['data'] = array(
    'mediaUrl' => "http://www.alphansotech.com/wp-content/uploads/2015/12/Push-notification-1.jpg", 
    'mediaType' => "jpg" 
); 

は、この部分を交換してみてください

$body = array(
    'aps' => array(
    'alert' => 'Rich notification', 
    'sound' => 'default', 
    'mutable-content' => 1 
), 
    'mediaUrl' => 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/FloorGoban.JPG/1024px-FloorGoban.JPG', 
    'mediaType' => 'image' 
); 

注意してください、そのイメージはべきhttps://

+0

を呼び出すが、私は、私は埋め込みコードリンク与えている間、ユーチューブの動画を再生することができないんですが、私は、すべての画像をサポートする必要があります私のコードを更新したいですビデオおよびオーディオ形式。 –

+0

私はプッシュでビデオを再生したいのですが、上のコードでそれをサポートしていないので、上記のコードからビデオを再生するのに役立ちます。 –

+0

@Ashrafでは、豊富なプッシュ通知の用途とプロジェクト作成について知るためのサンプルデモリンクを提供できますか? – Ramakrishna

5

この追加の警告は動作しません通知サービス の値を持ちます。はテストデバイスでサポートされていません。私のテストデバイスは10.1

ありながら通知サービステンプレートが自動的に10.2にそのDeployment Targetを設定していた

は、私の場合は、そのはすでにすべてに沿って仕事をしながら私の拡張設定を設定する時間を無駄に!

+0

これにも惑わされています。 –

関連する問題