简体   繁体   中英

Convert NS_OPTIONS enum (UIRemoteNotificationType) bitmask to NSString delimited value

I would like to convert a UIRemoteNotificationType into a string for use in analytics tracking. Something like "badge:sound:alert". What would be the preferred method for doing this using the latest CLANG Objective-C language features available in Xcode 5?

I've seen a number of other questions on doing single value NSEnum values using various techniques, notably here , and here . However, none of these discuss a solution for NS_OPTION based enums which contain multiple bitmask values.

My initial thought is that I'll need an NSDictionary to map the values and NSArray to collect them after iterating, is there a more elegant way to approach this?

Here is the solution I came up with, reasonably terse, but still type specific and brittle to future expansion:

from UIApplication.h typedef NS_OPTIONS(NSUInteger, UIRemoteNotificationType) { UIRemoteNotificationTypeNone = 0, UIRemoteNotificationTypeBadge = 1 << 0, UIRemoteNotificationTypeSound = 1 << 1, UIRemoteNotificationTypeAlert = 1 << 2, UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3, } NS_ENUM_AVAILABLE_IOS(3_0);

NSString* remoteNotificationTypesToString(UIRemoteNotificationType notificationTypes)
{
    NSArray *remoteNotificationTypeStrs = @[@"Badge", @"Sound", @"Alert", @"NewsStand"];
    NSMutableArray *enabledNotificationTypes = [[NSMutableArray alloc] init];

    #define kBitsUsedByUIRemoteNotificationType 4
    for (NSUInteger i=0; i < kBitsUsedByUIRemoteNotificationType; i++) {
        NSUInteger enumBitValueToCheck = 1 << i;
        if (notificationTypes & enumBitValueToCheck)
            [enabledNotificationTypes addObject:[remoteNotificationTypeStrs objectAtIndex:i]];
    }

    NSString *result = enabledNotificationTypes.count > 0 ?
                       [enabledNotificationTypes componentsJoinedByString:@":"] :
                       @"NotificationsDisabled";

    return result;
}

UIRemoteNotificationType notificationTypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
NSString *notificationTypesStr = remoteNotificationTypesToString(notificationTypes);
NSLog(@"Notification types: %@", notificationTypesStr);

In terms of elegance, I don't think there's a way (yet) to get the names of options in NS_ENUM or NS_OPTIONS , since they are just macros to the underlying C enum and don't add any OOP niceties. It would be nice if there was some NSEnum/NSOptions class wrapper that defined a method "getNames" for the underlying enum to do what you suggest, but unfortunately it doesn't exist yet.

So, back to reality here, the NSDictionary approach will definitely work, but how about just writing a simple helper method that does some bitwise operations and returns your NSString ? So if you have some NSInteger that represents your bitmask, you could write a method like so:

- (NSString *)optionsToSerializedString:(NSInteger)options{
    NSString *str = @"";

    if (options & UIRemoteNotificationTypeBadge) {
        str = [str stringByAppendingString:@"badge:"];
    }
    if (options & UIRemoteNotificationTypeAlert) {
        str = [str stringByAppendingString:@"alert:"];
    }
    //etc. etc. for other cases

    return str;
}

Note that this won't quite get it to the format that you'd like in your question ("badge:sound:alert"), but I'll leave that to you!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM