在 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 等机制,延长应用在后台的运行时间,以维持长连接。
这个方案提供了一个基本的封装思路,你可以根据具体需求进行调整和扩展。 记住,实现一个完善的推送通知功能需要考虑很多细节,建议逐步完善,并进行充分的测试。