iOS怎麼推送統計到達率

zeqinjie發表於2018-07-04

github地址

ios摘要

體系圖

類關係圖

直接進入正題如何統計到達

在iOS10中新增兩個擴充
  1. 其中的一個擴充UNNotificationServiceExtension 通知服務擴充套件
  • UNNotificationServiceExtension 是修改遠端推送攜帶的內容。
  • UNNotificationServiceExtension 類 可以讓開發者自定義推送展示的內容。你可以用 extension 修改推送內容和下載推送相關的資源。你可以在extension 中解密和加密的資料或下載推送相關的圖片

2.因此在這裡可以提交到達的請求注意是這裡處理時間只有30秒。為了不影響達到統計介面。一般會先發統計請求。同時通過快取減少圖片的請求。及圖片的大小處理。

@interface NotificationService ()<NSURLSessionDelegate>

@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];
    NSDictionary *userInfo = request.content.userInfo;
    
    NSString *iconUrl = userInfo[[self fcmPushStrFromStr:@"small_image"]];//小圖
    NSString *imageUrl = userInfo[[self fcmPushStrFromStr:@"image"]];//大圖
    
    //重點這裡傳送給後端到達統計
    [ProfessionTool sendFcmPushStatUserInfo:userInfo];//統計到達數
    
    //這裡是處理富文字圖片 ,媒體視訊等
    UNNotificationAttachment *iconAtt = [self attachmentWithUrl:iconUrl fileName:@"small_image"];//待優化快取方式
    UNNotificationAttachment *imageAtt = [self attachmentWithUrl:imageUrl fileName:@"image"];
    NSMutableArray *attArr = [NSMutableArray array];
    if (iconAtt) [attArr addObject:iconAtt];
    if (imageAtt) [attArr addObject:imageAtt];
    self.bestAttemptContent.attachments = attArr;
    self.contentHandler(self.bestAttemptContent);

}

- (UNNotificationAttachment *)attachmentWithUrl:(NSString *)url fileName:(NSString *)fileName{
    if (url) {
        UIImage *iconImg = [self getImageFromURL:url];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectoryPath = [paths firstObject];
        NSString *iconPath = [self saveImage:iconImg withFileName:fileName ofType:@"png" inDirectory:documentsDirectoryPath];
        if (iconPath && ![iconPath isEqualToString:@""]) {
            UNNotificationAttachment * attachment = [UNNotificationAttachment attachmentWithIdentifier:fileName URL:[NSURL URLWithString:[@"file://" stringByAppendingString:iconPath]] options:nil error:nil];
            if (attachment) {
                return attachment;
            }
        }
    }
    return nil;
}

- (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.contentHandler(self.bestAttemptContent);
}

#pragma mark - private Method
- (UIImage *)getImageFromURL:(NSString *)fileURL {
    DLog(@"執行圖片下載函式");
    UIImage * result;
    //dataWithContentsOfURL方法需要https連線
    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
    result = [UIImage imageWithData:data];
    
    return result;
}

//將所下載的圖片儲存到本地
- (NSString *)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
    NSString *urlStr = @"";
    if ([[extension lowercaseString] isEqualToString:@"png"]){
        urlStr = [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]];
        [UIImagePNGRepresentation(image) writeToFile:urlStr options:NSAtomicWrite error:nil];
        
    } else if ([[extension lowercaseString] isEqualToString:@"jpg"] ||
               [[extension lowercaseString] isEqualToString:@"jpeg"]){
        urlStr = [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]];
        [UIImageJPEGRepresentation(image, 1.0) writeToFile:urlStr options:NSAtomicWrite error:nil];
        
    } else{
        DLog(@"extension error");
    }
    return urlStr;
}

//因專案中使用google 的FCM推送收到的推送欄位有點不一樣
- (NSString *)fcmPushStrFromStr:(NSString *)str{
    NSString *resultStr = str;
    NSString *fcmPre = @"gcm.notification.";
    if (![resultStr containsString:fcmPre]) {
        resultStr = [NSString stringWithFormat:@"%@%@",fcmPre,resultStr];
    }
    return resultStr;
}
複製程式碼

3.服務端配置內容需要新增"mutable-content":1 (富文字推送) 很多人會搞混"content-available":1(靜默推送)

4.當然了google FCM的富文字推送是"mutable_content":"true" 國內用的比較多的是鐳射JPush.百度推送等。後續會寫篇google FCM 推送的配置方式


拿到的回撥內容
//iOS10 之前
{
"aps" : {
    "alert" : "title",
    "badge" : 1,
    "sound":"default"
        },
}

//iOS10 新增的文案多樣性
{
"aps" : {
    "alert" : { 
         "title" : "title", 
         "subtitle" : "subtitle",         
         "body" : "body"
                },
    "badge" : 1,
    "sound":"default"
        },
}

複製程式碼
//接收到推送回撥函式
//iOS1O之前的 

//NS_AVAILABLE_IOS(3_0)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    //最開始的接收推送回撥
}

//NS_AVAILABLE_IOS(7_0)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
    //這裡亦可接收靜默推送回撥   
}

//iOS10之後統一 
//  iOS10特性。App在前臺獲取通知

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

   completionHandler(UNNotificationPresentationOptionAlert);

}

//點選通知進入App
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    
}

複製程式碼

5.與之前不同是ios10前臺執行也能收到推送通知欄同樣在上面userNotificationCenter接收處理點選事件

6.當然本人曾在低於iOS10版本通用過pod 'JDStatusBarNotification'庫模仿一個推送通知欄

7.測試傳送iOS10的富文字推送低於iOS10版本的的使用者只能收到title. subtitle內容是獲取不到的。

8.Target的除錯 將專案執行起來,然後傳送一條推送之後,啟用Service Extension,在XCode -DEBUG下Attach to Process 選擇對於的target

相關文章