#import "WMFAnnouncementsFetcher.h" #import "WMFAnnouncement.h" #import #import @implementation WMFAnnouncementsFetcher - (void)fetchAnnouncementsForURL:(NSURL *)siteURL force:(BOOL)force failure:(WMFErrorHandler)failure success:(void (^)(NSArray *announcements))success { NSParameterAssert(siteURL); if (siteURL == nil) { NSError *error = [WMFFetcher invalidParametersError]; failure(error); return; } NSURL *url = [self.configuration announcementsAPIURLForURL:siteURL appendingPathComponents:@[@"feed", @"announcements"]]; [self.session getJSONDictionaryFromURL:url ignoreCache:YES completionHandler:^(NSDictionary * _Nullable result, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { failure(error); return; } if (response.statusCode == 304) { failure([WMFFetcher noNewDataError]); return; } NSError *serializerError = nil; NSArray *announcements = [WMFLegacySerializer modelsOfClass:[WMFAnnouncement class] fromArrayForKeyPath:@"announce" inJSONDictionary:result languageVariantCode:url.wmf_languageVariantCode error:&serializerError]; if (serializerError) { failure(serializerError); return; } NSString *geoIPCookie = [self geoIPCookieString]; NSString *setCookieHeader = nil; if ([response isKindOfClass:[NSHTTPURLResponse class]]) { setCookieHeader = [(NSHTTPURLResponse *)response allHeaderFields][@"Set-Cookie"]; } NSArray *announcementsFilteredByCountry = [self filterAnnouncements:announcements withCurrentCountryInIPHeader:setCookieHeader geoIPCookieValue:geoIPCookie]; NSArray *filteredAnnouncements = [self filterAnnouncementsForiOSPlatform:announcementsFilteredByCountry]; success(filteredAnnouncements); }]; } - (NSArray *)filterAnnouncements:(NSArray *)announcements withCurrentCountryInIPHeader:(NSString *)header geoIPCookieValue:(NSString *)cookieValue { NSArray *validAnnouncements = [announcements wmf_select:^BOOL(WMFAnnouncement *obj) { if (![obj isKindOfClass:[WMFAnnouncement class]]) { return NO; } NSArray *countries = [obj countries]; if (countries.count == 0) { return YES; } __block BOOL valid = NO; [countries enumerateObjectsUsingBlock:^(NSString *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { if ([header containsString:[NSString stringWithFormat:@"GeoIP=%@", obj]]) { valid = YES; *stop = YES; } if ([header length] < 1 && [cookieValue hasPrefix:obj]) { valid = YES; *stop = YES; } }]; return valid; }]; return validAnnouncements; } - (NSArray *)filterAnnouncementsForiOSPlatform:(NSArray *)announcements { NSArray *validAnnouncements = [announcements wmf_select:^BOOL(WMFAnnouncement *obj) { if (![obj isKindOfClass:[WMFAnnouncement class]]) { return NO; } if ([obj.platforms containsObject:@"iOSAppV5"]) { return YES; } else { return NO; } }]; return validAnnouncements; } - (NSString *)geoIPCookieString { NSArray *cookies = [[WMFSession sharedCookieStorage] cookies];; NSHTTPCookie *cookie = [cookies wmf_match:^BOOL(NSHTTPCookie *obj) { if ([[obj name] containsString:@"GeoIP"]) { return YES; } else { return NO; } }]; return [cookie value]; } @end