iOS开发中如何封装推送通知功能

6 阅读3分钟

在 iOS 开发中,封装推送通知功能并结合 HTTP 拉取离线消息和保持长连接,需要考虑多个方面。以下提供一个基于 Objective-C 的封装思路,并涵盖多种应用场景的兼容性:

iOS 推送通知封装

这个方案整合了 APNs 和 HTTP 拉取,并兼容了前台长连接的场景。

1. 创建 PushNotificationManager 类:

#import <Foundation/Foundation.h>
#import <UserNotifications/UserNotifications.h>

@interface PushNotificationManager : NSObject <UNUserNotificationCenterDelegate>

+ (instancetype)sharedManager;

- (void)registerForPushNotifications;
- (void)handlePushNotificationWithUserInfo:(NSDictionary *)userInfo;
- (void)fetchOfflineMessages;
- (void)establishLongConnectionIfNeeded;
- (void)disconnectLongConnection;
@property (nonatomic, assign, readonly) BOOL isRegisteredForRemoteNotifications; // 添加注册状态属性 

@end
#import "PushNotificationManager.h"

@interface PushNotificationManager ()

@property (nonatomic, strong) NSTimer *heartbeatTimer; // 心跳定时器 

@property (nonatomic, assign) BOOL manuallyDisconnected; // 手动断开标志 

@property (nonatomic, assign) BOOL isLongConnectionEstablished; // 长连接状态标志 
@property (nonatomic, assign) BOOL isRegisteredForRemoteNotifications; // 推送通知注册状态 


// ... 其他必要的属性,例如长连接管理对象等 

@end

@implementation PushNotificationManager

+ (instancetype)sharedManager {
    static PushNotificationManager *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

- (void)registerForPushNotifications {
    // 参考搜索结果中提到的注册推送通知代码 [1, 2, 3](https://gist.github.com/blitzcrank/d7f4034b6231df06d0f63bdd1ee7c172, https://www.back4app.com/docs/ios/push-notifications/best-ios-push-notification-service, https://stackoverflow.com/questions/47650010/how-to-implement-interactive-remote-notifications-in-ios-objective-c)
    // ... (iOS 10+ 注册代码)
}

- (void)handlePushNotificationWithUserInfo:(NSDictionary *)userInfo {
    // 处理接收到的推送通知
    // ... (根据 userInfo 内容进行不同的操作)
}

- (void)fetchOfflineMessages {
    // 使用 HTTP 请求拉取离线消息
    // ... (HTTP 请求代码,解析服务器返回的消息数据)
}

- (void)establishLongConnectionIfNeeded {
    // 建立长连接
    // ... (长连接建立代码,例如 WebSocket 或其他长连接方案)
}

- (void)disconnectLongConnection {
    // 断开长连接
    // ... (长连接断开代码)
}

// ... (其他方法,例如 UNUserNotificationCenterDelegate 的方法)

@end

2. APNs 推送和 HTTP 拉取:

  • APNs 主要用于实时性要求高的消息推送。
  • HTTP 拉取用于获取 APNs 无法送达时的离线消息,以及一些非实时消息。

3. 前台长连接:

  • 应用在前台时,可以建立长连接,例如 WebSocket,以实现更实时的消息交互。
  • establishLongConnectionIfNeeded 方法会在应用进入前台时调用,建立长连接。
  • disconnectLongConnection 方法会在应用进入后台时调用,断开长连接。

4. 多种应用场景兼容:

  • 通过 handlePushNotificationWithUserInfo 方法,可以根据不同的 userInfo 内容,进行不同的操作,从而兼容多种应用场景。
  • 例如,可以根据 userInfo 中的特定字段,跳转到不同的页面,或执行不同的逻辑。

5. 使用示例:

AppDelegate 中:


#import "AppDelegate.h"
#import "PushNotificationManager.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[PushNotificationManager sharedManager] registerForPushNotifications];
    return YES;
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [[PushNotificationManager sharedManager] handlePushNotificationWithUserInfo:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[PushNotificationManager sharedManager] establishLongConnectionIfNeeded];
    [[PushNotificationManager sharedManager] fetchOfflineMessages];
}

- (void)applicationWillResignActive:(UIApplication *)application {
    [[PushNotificationManager sharedManager] disconnectLongConnection];
}

@end

进一步改进:

  • 消息去重: 需要设计消息去重机制,避免重复显示消息。
  • 断线重连: 长连接断开后,需要实现自动重连机制。
  • 心跳机制: 为了保持长连接的活性,需要实现心跳机制。
  • 后台保活: 可以考虑使用 Background Tasks 等机制,延长应用在后台的运行时间,以维持长连接。

这个方案提供了一个基本的封装思路,你可以根据具体需求进行调整和扩展。 记住,实现一个完善的推送通知功能需要考虑很多细节,建议逐步完善,并进行充分的测试。