#import "WMFAnnouncement.h" #import #import #import #import @implementation WMFAnnouncement @synthesize actionURL = _actionURL; + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ WMF_SAFE_KEYPATH(WMFAnnouncement.new, identifier): @"id", WMF_SAFE_KEYPATH(WMFAnnouncement.new, type): @"type", WMF_SAFE_KEYPATH(WMFAnnouncement.new, startTime): @"start_time", WMF_SAFE_KEYPATH(WMFAnnouncement.new, endTime): @"end_time", WMF_SAFE_KEYPATH(WMFAnnouncement.new, platforms): @"platforms", WMF_SAFE_KEYPATH(WMFAnnouncement.new, countries): @"countries", WMF_SAFE_KEYPATH(WMFAnnouncement.new, placement): @"placement", WMF_SAFE_KEYPATH(WMFAnnouncement.new, text): @"text", WMF_SAFE_KEYPATH(WMFAnnouncement.new, actionTitle): @"action.title", WMF_SAFE_KEYPATH(WMFAnnouncement.new, actionURLString): @"action.url", WMF_SAFE_KEYPATH(WMFAnnouncement.new, captionHTML): @"caption_HTML", WMF_SAFE_KEYPATH(WMFAnnouncement.new, imageURL): @[@"image", @"image_url"], WMF_SAFE_KEYPATH(WMFAnnouncement.new, imageHeight): @"image_height", WMF_SAFE_KEYPATH(WMFAnnouncement.new, negativeText): @"negative_text", WMF_SAFE_KEYPATH(WMFAnnouncement.new, loggedIn): @"logged_in", WMF_SAFE_KEYPATH(WMFAnnouncement.new, readingListSyncEnabled): @"reading_list_sync_enabled", WMF_SAFE_KEYPATH(WMFAnnouncement.new, beta): @"beta", WMF_SAFE_KEYPATH(WMFAnnouncement.new, domain): @"domain", WMF_SAFE_KEYPATH(WMFAnnouncement.new, articleTitles): @"articleTitles", WMF_SAFE_KEYPATH(WMFAnnouncement.new, displayDelay): @"displayDelay", WMF_SAFE_KEYPATH(WMFAnnouncement.new, percentReceivingExperiment): @"percent_receiving_experiment" }; } + (NSInteger)version { return 4; } - (NSURL *)actionURL { if (!_actionURL) { _actionURL = [NSURL wmf_optionalURLWithString: self.actionURLString]; } return _actionURL; } + (NSValueTransformer *)imageURLJSONTransformer { return [MTLValueTransformer transformerUsingForwardBlock:^NSURL *(NSDictionary *value, BOOL *success, NSError *__autoreleasing *error) { NSString *urlString = value[@"image"] ?: value[@"image_url"]; return [NSURL wmf_optionalURLWithString:urlString]; } reverseBlock:^NSDictionary *(NSURL *URL, BOOL *success, NSError *__autoreleasing *error) { NSString *urlString = [URL absoluteString]; if (!urlString) { return @{}; } return @{@"image_url": urlString}; }]; } + (NSValueTransformer *)startTimeJSONTransformer { return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *value, BOOL *success, NSError *__autoreleasing *error) { NSDate *date = [[NSDateFormatter wmf_iso8601Formatter] dateFromString:value]; return date; }]; } + (NSValueTransformer *)endTimeJSONTransformer { return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *value, BOOL *success, NSError *__autoreleasing *error) { NSDate *date = [[NSDateFormatter wmf_iso8601Formatter] dateFromString:value]; return date; }]; } + (NSDictionary *)allowedSecureCodingClassesByPropertyKey { //Add NSString to list of allowed classes for NSArray properties. //This fixes the "[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type 'NSString' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set" console error in iOS 15 NSDictionary *superAllowedClassesDict = [super allowedSecureCodingClassesByPropertyKey]; NSMutableDictionary *allowedClassesDict = [[NSMutableDictionary alloc] initWithDictionary:superAllowedClassesDict]; NSArray *keysToCheck = @[@"countries", @"platforms", @"articleTitles"]; for (NSString *key in keysToCheck) { NSObject *object = [allowedClassesDict objectForKey:key]; if ([object isKindOfClass:[NSArray class]]) { NSMutableArray *allowedClasses = [NSMutableArray arrayWithArray:(NSArray *)object]; [allowedClasses addObject:[NSString class]]; [allowedClassesDict setObject:[NSArray arrayWithArray:allowedClasses] forKey:key]; } } return [NSDictionary dictionaryWithDictionary:allowedClassesDict]; } // No languageVariantCodePropagationSubelementKeys + (NSArray *)languageVariantCodePropagationURLKeys { return @[@"imageURL", @"actionURL"]; } @end