Apple Watch 中的 PubNub 框架

PubNub framework in Apple Watch

我一直在尝试手动将 PubNub 框架导入我的 Apple Watch 应用程序。 PubNub 使用的许多依赖项和框架在 watch 上不可用(即 SystemConfiguration、CFNetworking 等)。 PubNub 支持 Apple Watch 吗?如何将它很好地导入到我的 Apple Watch 应用程序中?

只需要进行一些修改。用 WatchKit 替代品替换 UIKit:

TLDR:

  • WKInterfaceDevice 替换 UIDevice
  • [[UIDevice currentDevice] identifierForDevice]替换为存储在NSUserDefaults
  • 中的UUID
  • UIApplicationWillEnterForegroundNotificationUIApplicationDidEnterBackgroundNotification替换为NSExtensionHostWillEnterForegroundNotificationNSExtensionHostDidEnterBackgroundNotification
  • 删除 GZIP 引用

文件详细说明:

PNConfiguration.m:

    - (NSString *)uniqueDeviceIdentifier {
#if TARGET_OS_WATCH
        NSString *key = @"PNUserDefaultsUUIDKey";
        NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:key];
        if (!uuid) {
            uuid = [[NSUUID UUID] UUIDString];
            [[NSUserDefaults standardUserDefaults] setValue:uuid forKey:key];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
        return uuid;
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
        return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
        return ([self serialNumber]?: [self macAddress]);
#endif
    }

PNNetwork.m:

    - (NSDictionary *)defaultHeaders {
        NSString *device = @"iPhone";
        NSString *osVersion = @"2.0";
#if TARGET_OS_WATCH
        osVersion = [[WKInterfaceDevice currentDevice] systemVersion];
        device = [[WKInterfaceDevice currentDevice] model];
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
        device = [[UIDevice currentDevice] model];
        osVersion = [[UIDevice currentDevice] systemVersion];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
        NSOperatingSystemVersion version = [[NSProcessInfo processInfo]operatingSystemVersion];
        NSMutableString *osVersion = [NSMutableString stringWithFormat:@"%@.%@",
                              @(version.majorVersion), @(version.minorVersion)];
        if (version.patchVersion > 0) {

            [osVersion appendFormat:@".%@", @(version.patchVersion)];
    }
#endif
        NSString *userAgent = [NSString stringWithFormat:@"iPhone; CPU %@ OS %@ Version",
                       device, osVersion];

         return @{@"Accept":@"*/*", @"Accept-Encoding":@"gzip,deflate", @"User-Agent":userAgent,
         @"Connection":@"keep-alive"};
    }

PubNub+Core.m:

    - (instancetype)initWithConfiguration:(PNConfiguration *)configuration
                    callbackQueue:(dispatch_queue_t)callbackQueue {

// Check whether initialization has been successful or not
        if ((self = [super init])) {
#if DEBUG
            [PNLog dumpToFile:YES];
#else
            [PNLog dumpToFile:NO];
#endif

            DDLogClientInfo([[self class] ddLogLevel], @"<PubNub> PubNub SDK %@ (%@)",
                    kPNLibraryVersion, kPNCommit);

            _configuration = [configuration copy];
            _callbackQueue = callbackQueue;
            [self prepareNetworkManagers];

            _subscriberManager = [PNSubscriber subscriberForClient:self];
            _clientStateManager = [PNClientState stateForClient:self];
            _listenersManager = [PNStateListener stateListenerForClient:self];
            _heartbeatManager = [PNHeartbeat heartbeatForClient:self];
            [self addListener:self];
            [self prepareReachability];
#if TARGET_OS_WATCH
            NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:NSExtensionHostWillEnterForegroundNotification object:nil];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:NSExtensionHostDidEnterBackgroundNotification object:nil];
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
            NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:UIApplicationWillEnterForegroundNotification object:nil];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:UIApplicationDidEnterBackgroundNotification object:nil];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
            NSNotificationCenter *notificationCenter = [[NSWorkspace sharedWorkspace] notifiertionCenter];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:NSWorkspaceWillSleepNotification object:nil];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:NSWorkspaceSessionDidResignActiveNotification object:nil];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:NSWorkspaceDidWakeNotification object:nil];
            [notificationCenter addObserver:self selector:@selector(handleContextTransition:)
                               name:NSWorkspaceSessionDidBecomeActiveNotification object:nil];
#endif
        }

        return self;
    }

PubNub+Core.m:

    - (void)handleContextTransition:(NSNotification *)notification {
#if TARGET_OS_WATCH
        if ([notification.name isEqualToString:NSExtensionHostDidEnterBackgroundNotification]) {

            DDLogClientInfo([[self class] ddLogLevel], @"<PubNub> Did enter background execution context.");
        }
        else if ([notification.name isEqualToString:NSExtensionHostWillEnterForegroundNotification]) {

            DDLogClientInfo([[self class] ddLogLevel], @"<PubNub> Will enter foreground execution context.");
        }
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
        if ([notification.name isEqualToString:UIApplicationDidEnterBackgroundNotification]) {

            DDLogClientInfo([[self class] ddLogLevel], @"<PubNub> Did enter background execution context.");
        }
        else if ([notification.name isEqualToString:UIApplicationWillEnterForegroundNotification]) {

            DDLogClientInfo([[self class] ddLogLevel], @"<PubNub> Will enter foreground execution context.");
        }
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
        if ([notification.name isEqualToString:NSWorkspaceWillSleepNotification] ||
        [notification.name isEqualToString:NSWorkspaceSessionDidResignActiveNotification]) {

            DDLogClientInfo([[self class] ddLogLevel], @"<PubNub> Workspace became inactive.");
        }
        else if ([notification.name isEqualToString:NSWorkspaceDidWakeNotification] ||
             [notification.name isEqualToString:NSWorkspaceSessionDidBecomeActiveNotification]) {

            DDLogClientInfo([[self class] ddLogLevel], @"<PubNub> Workspace became active.");
        }
#endif
    }

PubNub+Core.m:

    - (void)dealloc {
#if TARGET_OS_WATCH
        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
        [notificationCenter removeObserver:self name:NSExtensionHostWillEnterForegroundNotification
                            object:nil];
        [notificationCenter removeObserver:self name:NSExtensionHostDidEnterBackgroundNotification
                            object:nil];
#elif __IPHONE_OS_VERSION_MIN_REQUIRED
        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
        [notificationCenter removeObserver:self name:UIApplicationWillEnterForegroundNotification
                            object:nil];
        [notificationCenter removeObserver:self name:UIApplicationDidEnterBackgroundNotification
                            object:nil];
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
        NSNotificationCenter *notificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
        [notificationCenter removeObserver:self name:NSWorkspaceWillSleepNotification object:nil];
        [notificationCenter removeObserver:self name:NSWorkspaceSessionDidResignActiveNotification
                            object:nil];
        [notificationCenter removeObserver:self name:NSWorkspaceDidWakeNotification object:nil];
        [notificationCenter removeObserver:self name:NSWorkspaceSessionDidBecomeActiveNotification
                            object:nil];
#endif
    }

PubNub+Publish.m: 使用 PNGZIP 的地方

    NSData *publishData = nil;
    if (compressed) {
#if !TARGET_OS_WATCH
        NSData *messageData = [messageForPublish dataUsingEncoding:NSUTF8StringEncoding];
        NSData *compressedBody = [PNGZIP GZIPDeflatedData:messageData];
        publishData = (compressedBody?: [@"" dataUsingEncoding:NSUTF8StringEncoding]);
#else
        NSLog(@"Tried to compress, but GZip is not available");
#endif
    }