Mhurd has submitted this change and it was merged. Change subject: Fix memory "seepage" Bug T99260 ......................................................................
Fix memory "seepage" Bug T99260 Add memory semantics to property declarations in MWK model class Use properties for accessing properties Change-Id: I4938141e8cdfc76241bafd220d7362c32b55be6c --- M MediaWikiKit/MediaWikiKit/MWKArticle.h M MediaWikiKit/MediaWikiKit/MWKArticle.m M MediaWikiKit/MediaWikiKit/MWKDataStore.h M MediaWikiKit/MediaWikiKit/MWKDataStore.m M MediaWikiKit/MediaWikiKit/MWKHistoryEntry.h M MediaWikiKit/MediaWikiKit/MWKHistoryEntry.m M MediaWikiKit/MediaWikiKit/MWKHistoryList.h M MediaWikiKit/MediaWikiKit/MWKHistoryList.m M MediaWikiKit/MediaWikiKit/MWKImage.h M MediaWikiKit/MediaWikiKit/MWKImage.m M MediaWikiKit/MediaWikiKit/MWKImageInfo.h M MediaWikiKit/MediaWikiKit/MWKImageInfo.m M MediaWikiKit/MediaWikiKit/MWKImageList.h M MediaWikiKit/MediaWikiKit/MWKImageList.m M MediaWikiKit/MediaWikiKit/MWKLicense.h M MediaWikiKit/MediaWikiKit/MWKLicense.m M MediaWikiKit/MediaWikiKit/MWKProtectionStatus.m M MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.h M MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.m M MediaWikiKit/MediaWikiKit/MWKRecentSearchList.h M MediaWikiKit/MediaWikiKit/MWKRecentSearchList.m M MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.h M MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m M MediaWikiKit/MediaWikiKit/MWKSavedPageList.h M MediaWikiKit/MediaWikiKit/MWKSavedPageList.m M MediaWikiKit/MediaWikiKit/MWKSection.h M MediaWikiKit/MediaWikiKit/MWKSection.m M MediaWikiKit/MediaWikiKit/MWKSectionList.h M MediaWikiKit/MediaWikiKit/MWKSectionList.m M MediaWikiKit/MediaWikiKit/MWKSite.h M MediaWikiKit/MediaWikiKit/MWKSite.m M MediaWikiKit/MediaWikiKit/MWKSiteDataObject.h M MediaWikiKit/MediaWikiKit/MWKSiteDataObject.m M MediaWikiKit/MediaWikiKit/MWKTitle.h M MediaWikiKit/MediaWikiKit/MWKTitle.m M MediaWikiKit/MediaWikiKit/MWKUser.h M MediaWikiKit/MediaWikiKit/MWKUser.m M MediaWikiKit/MediaWikiKit/MWKUserDataStore.h M MediaWikiKit/MediaWikiKit/MWKUserDataStore.m M Wikipedia/Data/SchemaConverter.h M Wikipedia/Session/SessionSingleton.m 41 files changed, 593 insertions(+), 409 deletions(-) Approvals: Mhurd: Looks good to me, approved Bgerstle: Looks good to me, but someone else must approve diff --git a/MediaWikiKit/MediaWikiKit/MWKArticle.h b/MediaWikiKit/MediaWikiKit/MWKArticle.h index 93f55de..975dc07 100644 --- a/MediaWikiKit/MediaWikiKit/MWKArticle.h +++ b/MediaWikiKit/MediaWikiKit/MWKArticle.h @@ -26,30 +26,29 @@ } // Identifiers -@property (readonly) MWKSite* site; -@property (readonly) MWKTitle* title; -@property (readonly) MWKDataStore* dataStore; +@property (readonly, strong, nonatomic) MWKTitle* title; +@property (readonly, weak, nonatomic) MWKDataStore* dataStore; // Metadata -@property (readonly) MWKTitle* redirected; // optional -@property (readonly) NSDate* lastmodified; // required -@property (readonly) MWKUser* lastmodifiedby; // required -@property (readonly) int articleId; // required; -> 'id' -@property (readonly) int languagecount; // required; int -@property (readonly) NSString* displaytitle; // optional -@property (readonly) MWKProtectionStatus* protection; // required -@property (readonly) BOOL editable; // required +@property (readonly, strong, nonatomic) MWKTitle* redirected; // optional +@property (readonly, strong, nonatomic) NSDate* lastmodified; // required +@property (readonly, strong, nonatomic) MWKUser* lastmodifiedby; // required +@property (readonly, assign, nonatomic) int articleId; // required; -> 'id' +@property (readonly, assign, nonatomic) int languagecount; // required; int +@property (readonly, copy, nonatomic) NSString* displaytitle; // optional +@property (readonly, strong, nonatomic) MWKProtectionStatus* protection; // required +@property (readonly, assign, nonatomic) BOOL editable; // required -@property (readwrite, nonatomic) NSString* thumbnailURL; // optional; pulled separately via search -@property (readwrite, nonatomic) NSString* imageURL; // optional; pulled in article request +@property (readwrite, copy, nonatomic) NSString* thumbnailURL; // optional; pulled separately via search +@property (readwrite, copy, nonatomic) NSString* imageURL; // optional; pulled in article request -@property (readonly) NSString* entityDescription; // optional; currently pulled separately via wikidata +@property (readonly, copy, nonatomic) NSString* entityDescription; // optional; currently pulled separately via wikidata -@property (readonly) MWKSectionList* sections; +@property (readonly, strong, nonatomic) MWKSectionList* sections; -@property (readonly) MWKImageList* images; -@property (readonly) MWKImage* thumbnail; -@property (readonly) MWKImage* image; +@property (readonly, strong, nonatomic) MWKImageList* images; +@property (readonly, strong, nonatomic) MWKImage* thumbnail; +@property (readonly, strong, nonatomic) MWKImage* image; - (instancetype)initWithTitle:(MWKTitle*)title dataStore:(MWKDataStore*)dataStore; - (instancetype)initWithTitle:(MWKTitle*)title dataStore:(MWKDataStore*)dataStore dict:(NSDictionary*)dict; diff --git a/MediaWikiKit/MediaWikiKit/MWKArticle.m b/MediaWikiKit/MediaWikiKit/MWKArticle.m index c6cf2ab..424da87 100644 --- a/MediaWikiKit/MediaWikiKit/MWKArticle.m +++ b/MediaWikiKit/MediaWikiKit/MWKArticle.m @@ -9,15 +9,41 @@ #import "MediaWikiKit.h" #import <BlocksKit/BlocksKit.h> -@implementation MWKArticle { - MWKSectionList* _sections; -} +@interface MWKArticle () + +// Identifiers +@property (readwrite, strong, nonatomic) MWKTitle* title; +@property (readwrite, weak, nonatomic) MWKDataStore* dataStore; + +// Metadata +@property (readwrite, strong, nonatomic) MWKTitle* redirected; // optional +@property (readwrite, strong, nonatomic) NSDate* lastmodified; // required +@property (readwrite, strong, nonatomic) MWKUser* lastmodifiedby; // required +@property (readwrite, assign, nonatomic) int articleId; // required; -> 'id' +@property (readwrite, assign, nonatomic) int languagecount; // required; int +@property (readwrite, copy, nonatomic) NSString* displaytitle; // optional +@property (readwrite, strong, nonatomic) MWKProtectionStatus* protection; // required +@property (readwrite, assign, nonatomic) BOOL editable; // required + +@property (readwrite, copy, nonatomic) NSString* entityDescription; // optional; currently pulled separately via wikidata + +@property (readwrite, strong, nonatomic) MWKSectionList* sections; + +@property (readwrite, strong, nonatomic) MWKImageList* images; +@property (readwrite, strong, nonatomic) MWKImage* thumbnail; +@property (readwrite, strong, nonatomic) MWKImage* image; + +@end + +@implementation MWKArticle + +#pragma mark - Setup / Tear Down - (instancetype)initWithTitle:(MWKTitle*)title dataStore:(MWKDataStore*)dataStore { self = [self initWithSite:title.site]; if (self) { - _dataStore = dataStore; - _title = title; + self.dataStore = dataStore; + self.title = title; } return self; } @@ -29,6 +55,35 @@ } return self; } + +#pragma mark - NSObject + +- (BOOL)isEqual:(id)object { + if (object == nil) { + return NO; + } else if (![object isKindOfClass:[MWKArticle class]]) { + return NO; + } else { + MWKArticle* other = object; + return [self.site isEqual:other.site] && + (self.redirected == other.redirected || [self.redirected isEqual:other.redirected]) && + [self.lastmodified isEqual:other.lastmodified] && + [self.lastmodifiedby isEqual:other.lastmodifiedby] && + self.articleId == other.articleId && + self.languagecount == other.languagecount && + [self.displaytitle isEqualToString:other.displaytitle] && + [self.protection isEqual:other.protection] && + self.editable == other.editable && + (self.thumbnailURL == other.thumbnailURL || [self.thumbnailURL isEqualToString:other.thumbnailURL]) && + (self.imageURL == other.imageURL || [self.imageURL isEqualToString:other.imageURL]); + } +} + +- (NSString*)description { + return [NSString stringWithFormat:@"%@ %@", [super description], self.title.description]; +} + +#pragma mark - Import / Export - (id)dataExport { NSMutableDictionary* dict = [[NSMutableDictionary alloc] init]; @@ -63,42 +118,17 @@ return [NSDictionary dictionaryWithDictionary:dict]; } -- (BOOL)isEqual:(id)object { - if (object == nil) { - return NO; - } else if (![object isKindOfClass:[MWKArticle class]]) { - return NO; - } else { - MWKArticle* other = object; - return [self.site isEqual:other.site] && - (self.redirected == other.redirected || [self.redirected isEqual:other.redirected]) && - [self.lastmodified isEqual:other.lastmodified] && - [self.lastmodifiedby isEqual:other.lastmodifiedby] && - self.articleId == other.articleId && - self.languagecount == other.languagecount && - [self.displaytitle isEqualToString:other.displaytitle] && - [self.protection isEqual:other.protection] && - self.editable == other.editable && - (self.thumbnailURL == other.thumbnailURL || [self.thumbnailURL isEqualToString:other.thumbnailURL]) && - (self.imageURL == other.imageURL || [self.imageURL isEqualToString:other.imageURL]); - } -} - -- (NSString*)description { - return [NSString stringWithFormat:@"%@ %@", [super description], self.title.description]; -} - - (void)importMobileViewJSON:(NSDictionary*)dict { - _lastmodified = [self requiredDate:@"lastmodified" dict:dict]; - _lastmodifiedby = [self requiredUser:@"lastmodifiedby" dict:dict]; - _articleId = [[self requiredNumber:@"id" dict:dict] intValue]; - _languagecount = [[self requiredNumber:@"languagecount" dict:dict] intValue]; - _protection = [self requiredProtectionStatus:@"protection" dict:dict]; - _editable = [[self requiredNumber:@"editable" dict:dict] boolValue]; + self.lastmodified = [self requiredDate:@"lastmodified" dict:dict]; + self.lastmodifiedby = [self requiredUser:@"lastmodifiedby" dict:dict]; + self.articleId = [[self requiredNumber:@"id" dict:dict] intValue]; + self.languagecount = [[self requiredNumber:@"languagecount" dict:dict] intValue]; + self.protection = [self requiredProtectionStatus:@"protection" dict:dict]; + self.editable = [[self requiredNumber:@"editable" dict:dict] boolValue]; - _redirected = [self optionalTitle:@"redirected" dict:dict]; - _displaytitle = [self optionalString:@"displaytitle" dict:dict]; - _entityDescription = [self optionalString:@"description" dict:dict]; + self.redirected = [self optionalTitle:@"redirected" dict:dict]; + self.displaytitle = [self optionalString:@"displaytitle" dict:dict]; + self.entityDescription = [self optionalString:@"description" dict:dict]; // From mobileview API... if (dict[@"thumb"]) { @@ -117,9 +147,11 @@ }]; if ([sectionsData count] > 0) { - [self.sections setSections:sectionsData]; + self.sections = [[MWKSectionList alloc] initWithArticle:self sections:sectionsData]; } } + +#pragma mark - Image Helpers - (void)updateImageListsWithSourceURL:(NSString*)sourceURL inSection:(int)sectionId { if (sourceURL && sourceURL.length > 0) { @@ -166,6 +198,8 @@ } } +#pragma mark - Save + - (void)save { [self.dataStore saveArticle:self]; [self.images save]; @@ -182,13 +216,16 @@ } } +#pragma mark - Remove + - (void)remove { NSString* path = [self.dataStore pathForArticle:self]; [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; - - _sections = nil; - _images = nil; + self.sections = nil; + self.images = nil; } + +#pragma mark - Accessors - (MWKSectionList*)sections { if (_sections == nil) { @@ -201,25 +238,11 @@ return [self.sections count] > 0 ? YES : NO; } -#pragma mark - protection status methods - -- (MWKProtectionStatus*)requiredProtectionStatus:(NSString*)key dict:(NSDictionary*)dict { - NSDictionary* obj = [self requiredDictionary:key dict:dict]; - if (obj == nil) { - @throw [NSException exceptionWithName:@"MWKDataObjectException" - reason:@"missing required protection status field" - userInfo:@{@"key": key}]; - } else { - return [[MWKProtectionStatus alloc] initWithData:obj]; - } -} - - (MWKImage*)thumbnail { - if (self.thumbnailURL) { - return [self imageWithURL:self.thumbnailURL]; - } else { - return nil; + if (self.thumbnailURL && !_thumbnail) { + _thumbnail = [self imageWithURL:self.thumbnailURL]; } + return _thumbnail; } - (void)setThumbnailURL:(NSString*)thumbnailURL { @@ -233,11 +256,10 @@ } - (MWKImage*)image { - if (self.imageURL) { - return [self imageWithURL:self.imageURL]; - } else { - return nil; + if (self.imageURL && !_image) { + _image = [self imageWithURL:self.imageURL]; } + return _image; } - (MWKImageList*)images { @@ -247,4 +269,17 @@ return _images; } +#pragma mark - protection status methods + +- (MWKProtectionStatus*)requiredProtectionStatus:(NSString*)key dict:(NSDictionary*)dict { + NSDictionary* obj = [self requiredDictionary:key dict:dict]; + if (obj == nil) { + @throw [NSException exceptionWithName:@"MWKDataObjectException" + reason:@"missing required protection status field" + userInfo:@{@"key": key}]; + } else { + return [[MWKProtectionStatus alloc] initWithData:obj]; + } +} + @end diff --git a/MediaWikiKit/MediaWikiKit/MWKDataStore.h b/MediaWikiKit/MediaWikiKit/MWKDataStore.h index d9a277b..9a8af74 100644 --- a/MediaWikiKit/MediaWikiKit/MWKDataStore.h +++ b/MediaWikiKit/MediaWikiKit/MWKDataStore.h @@ -24,7 +24,7 @@ @interface MWKDataStore : NSObject -@property (readonly) NSString* basePath; +@property (readonly, copy, nonatomic) NSString* basePath; - (instancetype)initWithBasePath:(NSString*)basePath; diff --git a/MediaWikiKit/MediaWikiKit/MWKDataStore.m b/MediaWikiKit/MediaWikiKit/MWKDataStore.m index 49a0841..cc7b972 100644 --- a/MediaWikiKit/MediaWikiKit/MWKDataStore.m +++ b/MediaWikiKit/MediaWikiKit/MWKDataStore.m @@ -11,12 +11,18 @@ static NSString* const MWKImageInfoFilename = @"ImageInfo.plist"; +@interface MWKDataStore () + +@property (readwrite, copy, nonatomic) NSString* basePath; + +@end + @implementation MWKDataStore - (instancetype)initWithBasePath:(NSString*)basePath { self = [self init]; if (self) { - _basePath = [basePath copy]; + self.basePath = basePath; } return self; } diff --git a/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.h b/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.h index 34cd119..2993426 100644 --- a/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.h +++ b/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.h @@ -22,10 +22,10 @@ @interface MWKHistoryEntry : MWKSiteDataObject -@property (readonly) MWKTitle* title; -@property (readwrite) NSDate* date; -@property (readwrite) MWKHistoryDiscoveryMethod discoveryMethod; -@property (readwrite) int scrollPosition; +@property (readonly, strong, nonatomic) MWKTitle* title; +@property (readwrite, strong, nonatomic) NSDate* date; +@property (readwrite, assign, nonatomic) MWKHistoryDiscoveryMethod discoveryMethod; +@property (readwrite, assign, nonatomic) int scrollPosition; - (instancetype)initWithTitle:(MWKTitle*)title discoveryMethod:(MWKHistoryDiscoveryMethod)discoveryMethod; - (instancetype)initWithDict:(NSDictionary*)dict; diff --git a/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.m b/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.m index d8afc72..fa3e30a 100644 --- a/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.m +++ b/MediaWikiKit/MediaWikiKit/MWKHistoryEntry.m @@ -9,15 +9,21 @@ #import "MediaWikiKit.h" #import "WikipediaAppUtils.h" +@interface MWKHistoryEntry () + +@property (readwrite, strong, nonatomic) MWKTitle* title; + +@end + @implementation MWKHistoryEntry - (instancetype)initWithTitle:(MWKTitle*)title discoveryMethod:(MWKHistoryDiscoveryMethod)discoveryMethod { self = [self initWithSite:title.site]; if (self) { - _title = title; - _date = [[NSDate alloc] init]; - _discoveryMethod = discoveryMethod; - _scrollPosition = 0; + self.title = title; + self.date = [[NSDate alloc] init]; + self.discoveryMethod = discoveryMethod; + self.scrollPosition = 0; } return self; } @@ -29,7 +35,7 @@ self = [self initWithSite:[MWKSite siteWithDomain:domain language:language]]; if (self) { - _title = [self requiredTitle:@"title" dict:dict]; + self.title = [self requiredTitle:@"title" dict:dict]; self.date = [self requiredDate:@"date" dict:dict]; self.discoveryMethod = [MWKHistoryEntry discoveryMethodForString:[self requiredString:@"discoveryMethod" dict:dict]]; self.scrollPosition = [[self requiredNumber:@"scrollPosition" dict:dict] intValue]; diff --git a/MediaWikiKit/MediaWikiKit/MWKHistoryList.h b/MediaWikiKit/MediaWikiKit/MWKHistoryList.h index 52b7da1..4d3dc97 100644 --- a/MediaWikiKit/MediaWikiKit/MWKHistoryList.h +++ b/MediaWikiKit/MediaWikiKit/MWKHistoryList.h @@ -13,9 +13,9 @@ @interface MWKHistoryList : MWKDataObject <NSFastEnumeration> -@property (nonatomic, readonly) NSUInteger length; -@property (nonatomic, readwrite) BOOL dirty; -@property (nonatomic, readonly) MWKHistoryEntry* mostRecentEntry; +@property (nonatomic, readonly, assign) NSUInteger length; +@property (nonatomic, readwrite, assign) BOOL dirty; +@property (nonatomic, readonly, strong) MWKHistoryEntry* mostRecentEntry; - (MWKHistoryEntry*)entryAtIndex:(NSUInteger)index; - (MWKHistoryEntry*)entryForTitle:(MWKTitle*)title; diff --git a/MediaWikiKit/MediaWikiKit/MWKHistoryList.m b/MediaWikiKit/MediaWikiKit/MWKHistoryList.m index c2d1952..13b5d24 100644 --- a/MediaWikiKit/MediaWikiKit/MWKHistoryList.m +++ b/MediaWikiKit/MediaWikiKit/MWKHistoryList.m @@ -8,29 +8,35 @@ #import "MediaWikiKit.h" -@implementation MWKHistoryList { - NSMutableArray* entries; - NSMutableDictionary* entriesByTitle; -} +@interface MWKHistoryList () + +@property (nonatomic, readwrite, assign) NSUInteger length; +@property (nonatomic, readwrite, strong) MWKHistoryEntry* mostRecentEntry; +@property (nonatomic, strong) NSMutableArray* entries; +@property (nonatomic, strong) NSMutableDictionary* entriesByTitle; + +@end + +@implementation MWKHistoryList - (NSUInteger)length { - return [entries count]; + return [self.entries count]; } - (MWKHistoryEntry*)mostRecentEntry { - return [entries firstObject]; + return [self.entries firstObject]; } - (MWKHistoryEntry*)entryAtIndex:(NSUInteger)index { - return entries[index]; + return self.entries[index]; } - (MWKHistoryEntry*)entryForTitle:(MWKTitle*)title { - return entriesByTitle[title]; + return self.entriesByTitle[title]; } - (NSUInteger)indexForEntry:(MWKHistoryEntry*)entry { - return [entries indexOfObject:entry]; + return [self.entries indexOfObject:entry]; } - (MWKHistoryEntry*)entryAfterEntry:(MWKHistoryEntry*)entry { @@ -64,27 +70,27 @@ MWKHistoryEntry* oldEntry = [self entryForTitle:entry.title]; if (oldEntry) { // Replace the old entry and move to top - [entries removeObject:oldEntry]; + [self.entries removeObject:oldEntry]; } - [entries insertObject:entry atIndex:0]; - entriesByTitle[entry.title] = entry; - _dirty = YES; + [self.entries insertObject:entry atIndex:0]; + self.entriesByTitle[entry.title] = entry; + self.dirty = YES; } - (void)removeEntry:(MWKHistoryEntry*)entry { if (entry.title == nil) { return; } - [entries removeObject:entry]; - [entriesByTitle removeObjectForKey:entry.title]; - _dirty = YES; + [self.entries removeObject:entry]; + [self.entriesByTitle removeObjectForKey:entry.title]; + self.dirty = YES; } - (void)removeAllEntries; { - [entries removeAllObjects]; - [entriesByTitle removeAllObjects]; - _dirty = YES; + [self.entries removeAllObjects]; + [self.entriesByTitle removeAllObjects]; + self.dirty = YES; } #pragma mark - data i/o methods @@ -92,8 +98,8 @@ - (instancetype)init { self = [super init]; if (self) { - entries = [[NSMutableArray alloc] init]; - entriesByTitle = [[NSMutableDictionary alloc] init]; + self.entries = [[NSMutableArray alloc] init]; + self.entriesByTitle = [[NSMutableDictionary alloc] init]; } return self; } @@ -103,14 +109,14 @@ if (self) { NSArray* arr = dict[@"entries"]; if (arr) { - entries = [[NSMutableArray alloc] init]; + self.entries = [[NSMutableArray alloc] init]; for (NSDictionary* entryDict in arr) { MWKHistoryEntry* entry = [[MWKHistoryEntry alloc] initWithDict:entryDict]; - [entries addObject:entry]; - entriesByTitle[entry.title] = entry; + [self.entries addObject:entry]; + self.entriesByTitle[entry.title] = entry; } } - _dirty = NO; + self.dirty = NO; } return self; } @@ -118,18 +124,18 @@ - (id)dataExport { NSMutableArray* array = [[NSMutableArray alloc] init]; - for (MWKHistoryEntry* entry in entries) { + for (MWKHistoryEntry* entry in self.entries) { [array addObject:[entry dataExport]]; } - _dirty = NO; + self.dirty = NO; return @{@"entries": [NSArray arrayWithArray:array]}; } - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state objects:(__unsafe_unretained id [])stackbuf count:(NSUInteger)len { - return [entries countByEnumeratingWithState:state objects:stackbuf count:len]; + return [self.entries countByEnumeratingWithState:state objects:stackbuf count:len]; } @end diff --git a/MediaWikiKit/MediaWikiKit/MWKImage.h b/MediaWikiKit/MediaWikiKit/MWKImage.h index 3040a63..e6a9895 100644 --- a/MediaWikiKit/MediaWikiKit/MWKImage.h +++ b/MediaWikiKit/MediaWikiKit/MWKImage.h @@ -9,27 +9,26 @@ @interface MWKImage : MWKSiteDataObject // Identifiers -@property (readonly) MWKSite* site; -@property (readonly) MWKArticle* article; +@property (readonly, weak, nonatomic) MWKArticle* article; // Metadata, static -@property (readonly) NSString* sourceURL; -@property (readonly) NSString* extension; -@property (readonly) NSString* fileName; -@property (readonly) NSString* fileNameNoSizePrefix; +@property (readonly, copy, nonatomic) NSString* sourceURL; +@property (readonly, copy, nonatomic) NSString* extension; +@property (readonly, copy, nonatomic) NSString* fileName; +@property (readonly, copy, nonatomic) NSString* fileNameNoSizePrefix; // Metadata, variable -@property (copy) NSDate* dateLastAccessed; -@property (copy) NSDate* dateRetrieved; -@property (copy) NSString* mimeType; +@property (copy, nonatomic) NSDate* dateLastAccessed; +@property (copy, nonatomic) NSDate* dateRetrieved; +@property (copy, nonatomic) NSString* mimeType; -@property (copy) NSNumber* width; -@property (copy) NSNumber* height; +@property (copy, nonatomic) NSNumber* width; +@property (copy, nonatomic) NSNumber* height; - (CGSize)size; // Local storage status -@property (readonly) BOOL isCached; +@property (readonly, assign, nonatomic) BOOL isCached; - (instancetype)initWithArticle:(MWKArticle*)article sourceURL:(NSString*)url; - (instancetype)initWithArticle:(MWKArticle*)article dict:(NSDictionary*)dict; @@ -45,7 +44,7 @@ * All focal rects as strings. Calculated via "calculateFocalRectsBasedOnFaceDetectionWithImageData" * Normally you do not need to access this directly, instead use the methods */ -@property (copy, readonly) NSArray* focalRectsInUnitCoordinatesAsStrings; +@property (readonly, copy, nonatomic) NSArray* focalRectsInUnitCoordinatesAsStrings; /** * Returns the primary focal rect diff --git a/MediaWikiKit/MediaWikiKit/MWKImage.m b/MediaWikiKit/MediaWikiKit/MWKImage.m index af31202..80c044b 100644 --- a/MediaWikiKit/MediaWikiKit/MWKImage.m +++ b/MediaWikiKit/MediaWikiKit/MWKImage.m @@ -9,27 +9,34 @@ @interface MWKImage () -@property (copy, readwrite) NSArray* focalRectsInUnitCoordinatesAsStrings; +// Identifiers +@property (readwrite, weak, nonatomic) MWKArticle* article; + +// Metadata, static +@property (readwrite, copy, nonatomic) NSString* sourceURL; +@property (readwrite, copy, nonatomic) NSString* extension; +@property (readwrite, copy, nonatomic) NSString* fileName; +@property (readwrite, copy, nonatomic) NSString* fileNameNoSizePrefix; + +@property (readwrite, assign, nonatomic) BOOL isCached; + +@property (readwrite, copy, nonatomic) NSArray* focalRectsInUnitCoordinatesAsStrings; @end @implementation MWKImage -@synthesize fileNameNoSizePrefix = _fileNameNoSizePrefix; + +#pragma mark - Setup - (instancetype)initWithArticle:(MWKArticle*)article sourceURL:(NSString*)url { self = [super initWithSite:article.site]; if (self) { - _article = article; + self.article = article; // fileNameNoSizePrefix is lazily derived from this property, so be careful if _sourceURL needs to be re-set - _sourceURL = [url copy]; + self.sourceURL = url; - _dateLastAccessed = nil; - _dateRetrieved = nil; - _mimeType = nil; - _width = nil; - _height = nil; - _focalRectsInUnitCoordinatesAsStrings = @[]; + self.focalRectsInUnitCoordinatesAsStrings = @[]; } return self; } @@ -38,12 +45,12 @@ NSString* sourceURL = [self requiredString:@"sourceURL" dict:dict]; self = [self initWithArticle:article sourceURL:sourceURL]; if (self) { - _dateLastAccessed = [self optionalDate:@"dateLastAccessed" dict:dict]; - _dateRetrieved = [self optionalDate:@"dateRetrieved" dict:dict]; - _mimeType = [self optionalString:@"mimeType" dict:dict]; - _width = [self optionalNumber:@"width" dict:dict]; - _height = [self optionalNumber:@"height" dict:dict]; - _focalRectsInUnitCoordinatesAsStrings = dict[@"focalRects"]; + self.dateLastAccessed = [self optionalDate:@"dateLastAccessed" dict:dict]; + self.dateRetrieved = [self optionalDate:@"dateRetrieved" dict:dict]; + self.mimeType = [self optionalString:@"mimeType" dict:dict]; + self.width = [self optionalNumber:@"width" dict:dict]; + self.height = [self optionalNumber:@"height" dict:dict]; + self.focalRectsInUnitCoordinatesAsStrings = dict[@"focalRects"]; } return self; } @@ -156,6 +163,8 @@ return _fileNameNoSizePrefix; } +#pragma mark - Import / Export + - (id)dataExport { NSMutableDictionary* dict = [[NSMutableDictionary alloc] init]; dict[@"sourceURL"] = self.sourceURL; @@ -186,14 +195,14 @@ } - (void)updateWithData:(NSData*)data { - _dateRetrieved = [[NSDate alloc] init]; - _dateLastAccessed = [[NSDate alloc] init]; - _mimeType = [self getImageMimeTypeForExtension:self.extension]; + self.dateRetrieved = [[NSDate alloc] init]; + self.dateLastAccessed = [[NSDate alloc] init]; + self.mimeType = [self getImageMimeTypeForExtension:self.extension]; - if (!_width || !_height) { + if (!self.width || !self.height) { UIImage* img = [UIImage imageWithData:data]; - _width = [NSNumber numberWithInt:img.size.width]; - _height = [NSNumber numberWithInt:img.size.height]; + self.width = [NSNumber numberWithInt:img.size.width]; + self.height = [NSNumber numberWithInt:img.size.height]; } } @@ -215,7 +224,7 @@ } - (void)updateLastAccessed { - _dateLastAccessed = [[NSDate alloc] init]; + self.dateLastAccessed = [[NSDate alloc] init]; } - (void)save { diff --git a/MediaWikiKit/MediaWikiKit/MWKImageInfo.h b/MediaWikiKit/MediaWikiKit/MWKImageInfo.h index e7bd91c..3327ecb 100644 --- a/MediaWikiKit/MediaWikiKit/MWKImageInfo.h +++ b/MediaWikiKit/MediaWikiKit/MWKImageInfo.h @@ -17,33 +17,33 @@ @property (nonatomic, readonly, copy) NSString* canonicalPageTitle; /// URL pointing at the canonical file associated with this gallery item, e.g. @c "//site/.../Some_file_name.extension". -@property (nonatomic, readonly) NSURL* canonicalFileURL; +@property (nonatomic, readonly, copy) NSURL* canonicalFileURL; /// Short description of the image contents (e.g. "John Smith posing for a picture"). @property (nonatomic, readonly, copy) NSString* imageDescription; -@property (nonatomic, readonly) MWKLicense* license; +@property (nonatomic, readonly, strong) MWKLicense* license; /// URL pointing to the corresponding file page for the receiver. -@property (nonatomic, readonly) NSURL* filePageURL; +@property (nonatomic, readonly, copy) NSURL* filePageURL; /// URL pointing at the original image (at the uploaded resolution). -@property (nonatomic, readonly) NSURL* imageURL; +@property (nonatomic, readonly, copy) NSURL* imageURL; /// URL pointing at a thumbnail version of the image at @c imageURL. -@property (nonatomic, readonly) NSURL* imageThumbURL; +@property (nonatomic, readonly, copy) NSURL* imageThumbURL; /// Size of the original image. -@property (nonatomic, readonly) CGSize imageSize; +@property (nonatomic, readonly, assign) CGSize imageSize; /// Size of the thumbnail at @c imageThumbURL. -@property (nonatomic, readonly) CGSize thumbSize; +@property (nonatomic, readonly, assign) CGSize thumbSize; /// Name of the entity owning this image. @property (nonatomic, readonly, copy) NSString* owner; /// Value which can be used to associate the receiver with a @c MWKImage. -@property (nonatomic, readonly) id imageAssociationValue; +@property (nonatomic, readonly, strong) id imageAssociationValue; /// Factory method for creating an instance from the output of @c exportData. + (instancetype)imageInfoWithExportedData:(NSDictionary*)exportedData; diff --git a/MediaWikiKit/MediaWikiKit/MWKImageInfo.m b/MediaWikiKit/MediaWikiKit/MWKImageInfo.m index b37c82c..023ebb3 100644 --- a/MediaWikiKit/MediaWikiKit/MWKImageInfo.m +++ b/MediaWikiKit/MediaWikiKit/MWKImageInfo.m @@ -19,8 +19,25 @@ NSString* const MWKImageInfoImageSize = @"imageSize"; NSString* const MWKImageInfoThumbSize = @"thumbSize"; + +@interface MWKImageInfo () + +@property (nonatomic, readwrite, copy) NSString* canonicalPageTitle; +@property (nonatomic, readwrite, copy) NSURL* canonicalFileURL; +@property (nonatomic, readwrite, copy) NSString* imageDescription; +@property (nonatomic, readwrite, strong) MWKLicense* license; +@property (nonatomic, readwrite, copy) NSURL* filePageURL; +@property (nonatomic, readwrite, copy) NSURL* imageURL; +@property (nonatomic, readwrite, copy) NSURL* imageThumbURL; +@property (nonatomic, readwrite, assign) CGSize imageSize; +@property (nonatomic, readwrite, assign) CGSize thumbSize; +@property (nonatomic, readwrite, copy) NSString* owner; +@property (nonatomic, readwrite, strong) id imageAssociationValue; + +@end + + @implementation MWKImageInfo -@synthesize imageAssociationValue = _imageAssociationValue; - (instancetype)initWithCanonicalPageTitle:(NSString*)canonicalPageTitle canonicalFileURL:(NSURL*)canonicalFileURL @@ -38,16 +55,16 @@ //NSParameterAssert([imageURL.absoluteString length]); self = [super init]; if (self) { - _canonicalPageTitle = [canonicalPageTitle copy]; - _imageDescription = [imageDescription copy]; - _owner = [owner copy]; - _license = license; - _canonicalFileURL = canonicalFileURL; - _filePageURL = filePageURL; - _imageURL = imageURL; - _imageThumbURL = imageThumbURL; - _imageSize = imageSize; - _thumbSize = thumbSize; + self.canonicalPageTitle = canonicalPageTitle; + self.imageDescription = imageDescription; + self.owner = owner; + self.license = license; + self.canonicalFileURL = canonicalFileURL; + self.filePageURL = filePageURL; + self.imageURL = imageURL; + self.imageThumbURL = imageThumbURL; + self.imageSize = imageSize; + self.thumbSize = thumbSize; } return self; } diff --git a/MediaWikiKit/MediaWikiKit/MWKImageList.h b/MediaWikiKit/MediaWikiKit/MWKImageList.h index 9cd780a..9620ded 100644 --- a/MediaWikiKit/MediaWikiKit/MWKImageList.h +++ b/MediaWikiKit/MediaWikiKit/MWKImageList.h @@ -13,8 +13,9 @@ @class MWKImage; @interface MWKImageList : MWKSiteDataObject <NSFastEnumeration> -@property (weak, readonly) MWKArticle* article; -@property (weak, readonly) MWKSection* section; + +@property (weak, readonly, nonatomic) MWKArticle* article; +@property (weak, readonly, nonatomic) MWKSection* section; - (instancetype)initWithArticle:(MWKArticle*)article section:(MWKSection*)section; - (instancetype)initWithArticle:(MWKArticle*)article section:(MWKSection*)section dict:(NSDictionary*)dict; diff --git a/MediaWikiKit/MediaWikiKit/MWKImageList.m b/MediaWikiKit/MediaWikiKit/MWKImageList.m index 9e90a51..63d5208 100644 --- a/MediaWikiKit/MediaWikiKit/MWKImageList.m +++ b/MediaWikiKit/MediaWikiKit/MWKImageList.m @@ -9,20 +9,28 @@ #import "MediaWikiKit.h" #import "NSString+Extras.h" -@implementation MWKImageList { - NSMutableArray* entries; - NSMutableDictionary* entriesByURL; - NSMutableDictionary* entriesByNameWithoutSize; - unsigned long mutationState; -} +@interface MWKImageList () + +@property (weak, readwrite, nonatomic) MWKArticle* article; +@property (weak, readwrite, nonatomic) MWKSection* section; + +@property (strong, nonatomic) NSMutableArray* entries; +@property (strong, nonatomic) NSMutableDictionary* entriesByURL; +@property (strong, nonatomic) NSMutableDictionary* entriesByNameWithoutSize; + +@property (assign, nonatomic) unsigned long mutationState; + +@end + +@implementation MWKImageList - (instancetype)initWithSite:(MWKSite*)site { self = [super initWithSite:site]; if (self) { - entries = [[NSMutableArray alloc] init]; - mutationState = 0; - entriesByURL = [[NSMutableDictionary alloc] init]; - entriesByNameWithoutSize = [[NSMutableDictionary alloc] init]; + self.entries = [[NSMutableArray alloc] init]; + self.mutationState = 0; + self.entriesByURL = [[NSMutableDictionary alloc] init]; + self.entriesByNameWithoutSize = [[NSMutableDictionary alloc] init]; } return self; } @@ -30,8 +38,8 @@ - (instancetype)initWithArticle:(MWKArticle*)article section:(MWKSection*)section { self = [self initWithSite:section.site]; if (self) { - _article = article; - _section = section; + self.article = article; + self.section = section; } return self; } @@ -49,26 +57,26 @@ - (void)addImageURL:(NSString*)imageURL { imageURL = [imageURL wmf_schemelessURL]; - [entries addObject:imageURL]; - entriesByURL[imageURL] = imageURL; + [self.entries addObject:imageURL]; + self.entriesByURL[imageURL] = imageURL; NSString* key = [MWKImage fileNameNoSizePrefix:imageURL]; - NSMutableArray* byname = entriesByNameWithoutSize[key]; + NSMutableArray* byname = self.entriesByNameWithoutSize[key]; if (byname == nil) { - byname = [[NSMutableArray alloc] init]; - entriesByNameWithoutSize[key] = byname; + byname = [[NSMutableArray alloc] init]; + self.entriesByNameWithoutSize[key] = byname; } [byname addObject:imageURL]; - mutationState++; + self.mutationState++; } - (NSUInteger)count { - return [entries count]; + return [self.entries count]; } - (NSString*)imageURLAtIndex:(NSUInteger)index { - if (index < [entries count]) { - return entries[index]; + if (index < [self.entries count]) { + return self.entries[index]; } else { return nil; } @@ -92,7 +100,7 @@ return nil; } NSString* baseName = [MWKImage fileNameNoSizePrefix:imageURL]; - NSMutableArray* arr = entriesByNameWithoutSize[baseName]; + NSMutableArray* arr = self.entriesByNameWithoutSize[baseName]; if (arr) { NSMutableArray* arr2 = [NSMutableArray arrayWithArray:arr]; @@ -156,19 +164,19 @@ } - (NSUInteger)indexOfImage:(MWKImage*)image { - return [entries indexOfObject:image.sourceURL]; + return [self.entries indexOfObject:image.sourceURL]; } - (BOOL)containsImage:(MWKImage*)image { - return [entries containsObject:image.sourceURL]; + return [self.entries containsObject:image.sourceURL]; } - (NSArray*)uniqueLargestVariants { - if (!entries || entries.count == 0) { + if (!self.entries || self.entries.count == 0) { return nil; } - NSMutableOrderedSet* resultBuilder = [[NSMutableOrderedSet alloc] initWithCapacity:entries.count]; - for (NSString* sourceURL in entries) { + NSMutableOrderedSet* resultBuilder = [[NSMutableOrderedSet alloc] initWithCapacity:self.entries.count]; + for (NSString* sourceURL in self.entries) { MWKImage* image = [self largestImageVariantForURL:sourceURL cachedOnly:NO]; NSAssert(image, @"Couldn't retrieve image record for image list entry: %@", sourceURL); [resultBuilder addObject:image]; @@ -177,7 +185,7 @@ } - (BOOL)addImageURLIfAbsent:(NSString*)imageURL { - if (imageURL && imageURL.length > 0 && ![entries containsObject:imageURL]) { + if (imageURL && imageURL.length > 0 && ![self.entries containsObject:imageURL]) { [self addImageURL:imageURL]; return YES; } else { @@ -188,7 +196,7 @@ #pragma mark - data i/o - (id)dataExport { - return @{@"entries": entries}; + return @{@"entries": self.entries}; } - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state @@ -204,7 +212,7 @@ state->state += count; state->itemsPtr = stackbuf; - state->mutationsPtr = &mutationState; + state->mutationsPtr = &_mutationState; return count; } diff --git a/MediaWikiKit/MediaWikiKit/MWKLicense.h b/MediaWikiKit/MediaWikiKit/MWKLicense.h index d288b50..75ead01 100644 --- a/MediaWikiKit/MediaWikiKit/MWKLicense.h +++ b/MediaWikiKit/MediaWikiKit/MWKLicense.h @@ -11,10 +11,8 @@ @interface MWKLicense : MWKDataObject @property (nonatomic, readonly, copy) NSString* code; - @property (nonatomic, readonly, copy) NSString* shortDescription; - -@property (nonatomic, readonly) NSURL* URL; +@property (nonatomic, readonly, copy) NSURL* URL; + (instancetype)licenseWithExportedData:(NSDictionary*)exportedData; diff --git a/MediaWikiKit/MediaWikiKit/MWKLicense.m b/MediaWikiKit/MediaWikiKit/MWKLicense.m index e6f631d..499c03d 100644 --- a/MediaWikiKit/MediaWikiKit/MWKLicense.m +++ b/MediaWikiKit/MediaWikiKit/MWKLicense.m @@ -13,6 +13,14 @@ static NSString* const MWKLicenseShortDescKey = @"shortDescription"; static NSString* const MWKLicenseURLKey = @"URL"; +@interface MWKLicense () + +@property (nonatomic, readwrite, copy) NSString* code; +@property (nonatomic, readwrite, copy) NSString* shortDescription; +@property (nonatomic, readwrite, copy) NSURL* URL; + +@end + @implementation MWKLicense - (instancetype)initWithCode:(NSString*)code @@ -20,9 +28,9 @@ URL:(NSURL*)URL { self = [super init]; if (self) { - _code = [code copy]; - _shortDescription = [shortDescription copy]; - _URL = URL; + self.code = code; + self.shortDescription = shortDescription; + self.URL = URL; } return self; } diff --git a/MediaWikiKit/MediaWikiKit/MWKProtectionStatus.m b/MediaWikiKit/MediaWikiKit/MWKProtectionStatus.m index f586026..7ef0f2c 100644 --- a/MediaWikiKit/MediaWikiKit/MWKProtectionStatus.m +++ b/MediaWikiKit/MediaWikiKit/MWKProtectionStatus.m @@ -8,25 +8,29 @@ #import "MediaWikiKit.h" -@implementation MWKProtectionStatus { - NSDictionary* _protection; -} +@interface MWKProtectionStatus () + +@property (nonatomic, strong) NSDictionary* protection; + +@end + +@implementation MWKProtectionStatus - (instancetype)initWithData:(id)data { self = [self init]; if (self) { NSDictionary* wrapper = @{@"protection": data}; - _protection = [self requiredDictionary:@"protection" dict:wrapper]; + self.protection = [self requiredDictionary:@"protection" dict:wrapper]; } return self; } - (NSArray*)protectedActions { - return [_protection allKeys]; + return [self.protection allKeys]; } - (NSArray*)allowedGroupsForAction:(NSString*)action { - return _protection[action]; + return self.protection[action]; } - (BOOL)isEqual:(id)object { @@ -52,7 +56,7 @@ } - (id)dataExport { - return _protection; + return self.protection; } - (id)copyWithZone:(NSZone*)zone { diff --git a/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.h b/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.h index 377c1f0..b6bba67 100644 --- a/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.h +++ b/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.h @@ -10,7 +10,7 @@ @interface MWKRecentSearchEntry : MWKSiteDataObject -@property (readonly) NSString* searchTerm; +@property (readonly, copy, nonatomic) NSString* searchTerm; - (instancetype)initWithSite:(MWKSite*)site searchTerm:(NSString*)searchTerm; - (instancetype)initWithDict:(NSDictionary*)dict; diff --git a/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.m b/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.m index ea962cc..a648355 100644 --- a/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.m +++ b/MediaWikiKit/MediaWikiKit/MWKRecentSearchEntry.m @@ -8,12 +8,18 @@ #import "MediaWikiKit.h" +@interface MWKRecentSearchEntry () + +@property (readwrite, copy, nonatomic) NSString* searchTerm; + +@end + @implementation MWKRecentSearchEntry - (instancetype)initWithSite:(MWKSite*)site searchTerm:(NSString*)searchTerm { self = [self initWithSite:site]; if (self) { - _searchTerm = searchTerm; + self.searchTerm = searchTerm; } return self; } diff --git a/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.h b/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.h index bb46af0..22d5463 100644 --- a/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.h +++ b/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.h @@ -12,8 +12,8 @@ @interface MWKRecentSearchList : MWKDataObject -@property (readonly) NSUInteger length; -@property (readonly) BOOL dirty; +@property (readonly, nonatomic, assign) NSUInteger length; +@property (readonly, nonatomic, assign) BOOL dirty; - (MWKRecentSearchEntry*)entryAtIndex:(NSUInteger)index; - (void)addEntry:(MWKRecentSearchEntry*)entry; diff --git a/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.m b/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.m index 404aa85..9152e34 100644 --- a/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.m +++ b/MediaWikiKit/MediaWikiKit/MWKRecentSearchList.m @@ -8,16 +8,22 @@ #import "MediaWikiKit.h" -@implementation MWKRecentSearchList { - NSMutableArray* entries; -} +@interface MWKRecentSearchList () + +@property (readwrite, nonatomic, assign) NSUInteger length; +@property (readwrite, nonatomic, assign) BOOL dirty; +@property (nonatomic, strong) NSMutableArray* entries; + +@end + +@implementation MWKRecentSearchList - (instancetype)init { self = [super init]; if (self) { - entries = [[NSMutableArray alloc] init]; + self.entries = [[NSMutableArray alloc] init]; } - _dirty = NO; + self.dirty = NO; return self; } @@ -26,35 +32,35 @@ if (self) { for (NSDictionary* entryDict in dict[@"entries"]) { MWKRecentSearchEntry* entry = [[MWKRecentSearchEntry alloc] initWithDict:entryDict]; - [entries addObject:entry]; + [self.entries addObject:entry]; } } - _dirty = NO; + self.dirty = NO; return self; } - (id)dataExport { NSMutableArray* dicts = [[NSMutableArray alloc] init]; - for (MWKRecentSearchEntry* entry in entries) { + for (MWKRecentSearchEntry* entry in self.entries) { [dicts addObject:[entry dataExport]]; } - _dirty = NO; + self.dirty = NO; return @{@"entries": dicts}; } - (void)addEntry:(MWKRecentSearchEntry*)entry { - NSUInteger oldIndex = [entries indexOfObject:entry]; + NSUInteger oldIndex = [self.entries indexOfObject:entry]; if (oldIndex != NSNotFound) { // Move to top! - [entries removeObjectAtIndex:oldIndex]; + [self.entries removeObjectAtIndex:oldIndex]; } - [entries insertObject:entry atIndex:0]; - _dirty = YES; + [self.entries insertObject:entry atIndex:0]; + self.dirty = YES; // @todo trim to max? } - (MWKRecentSearchEntry*)entryAtIndex:(NSUInteger)index { - return entries[index]; + return self.entries[index]; } @end diff --git a/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.h b/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.h index 0a83564..ab888f4 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.h +++ b/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.h @@ -10,8 +10,8 @@ @interface MWKSavedPageEntry : MWKSiteDataObject -@property (readonly) MWKTitle* title; -@property (readwrite) NSDate* date; +@property (readonly, strong, nonatomic) MWKTitle* title; +@property (readwrite, strong, nonatomic) NSDate* date; - (instancetype)initWithTitle:(MWKTitle*)title; - (instancetype)initWithDict:(NSDictionary*)dict; diff --git a/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m b/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m index c8b1129..0f424c0 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m +++ b/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m @@ -8,13 +8,18 @@ #import "MediaWikiKit.h" +@interface MWKSavedPageEntry () + +@property (readwrite, strong, nonatomic) MWKTitle* title; + +@end @implementation MWKSavedPageEntry - (instancetype)initWithTitle:(MWKTitle*)title { self = [self initWithSite:title.site]; if (self) { - _title = title; - _date = [[NSDate alloc] init]; + self.title = title; + self.date = [[NSDate alloc] init]; } return self; } @@ -26,7 +31,7 @@ self = [self initWithSite:[MWKSite siteWithDomain:domain language:language]]; if (self) { - _title = [self requiredTitle:@"title" dict:dict]; + self.title = [self requiredTitle:@"title" dict:dict]; } return self; } diff --git a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h index 5d3993e..fda336a 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h +++ b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h @@ -13,8 +13,8 @@ @interface MWKSavedPageList : MWKDataObject <NSFastEnumeration> -@property (readonly) NSUInteger length; -@property (readonly) BOOL dirty; +@property (readonly, nonatomic, assign) NSUInteger length; +@property (readonly, nonatomic, assign) BOOL dirty; - (MWKSavedPageEntry*)entryAtIndex:(NSUInteger)index; - (NSUInteger)indexForEntry:(MWKSavedPageEntry*)entry; diff --git a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m index 5c9b3c0..711b142 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m +++ b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m @@ -8,21 +8,26 @@ #import "MediaWikiKit.h" -@implementation MWKSavedPageList { - NSMutableArray* entries; - NSMutableDictionary* entriesByTitle; -} +@interface MWKSavedPageList () + +@property (nonatomic, strong) NSMutableArray* entries; +@property (nonatomic, strong) NSMutableDictionary* entriesByTitle; +@property (readwrite, nonatomic, assign) BOOL dirty; + +@end + +@implementation MWKSavedPageList - (NSUInteger)length { - return [entries count]; + return [self.entries count]; } - (MWKSavedPageEntry*)entryAtIndex:(NSUInteger)index { - return entries[index]; + return self.entries[index]; } - (MWKSavedPageEntry*)entryForTitle:(MWKTitle*)title { - MWKSavedPageEntry* entry = entriesByTitle[title]; + MWKSavedPageEntry* entry = self.entriesByTitle[title]; return entry; } @@ -32,7 +37,7 @@ } - (NSUInteger)indexForEntry:(MWKHistoryEntry*)entry { - return [entries indexOfObject:entry]; + return [self.entries indexOfObject:entry]; } #pragma mark - update methods @@ -40,22 +45,22 @@ - (void)addEntry:(MWKSavedPageEntry*)entry { if ([self entryForTitle:entry.title] == nil) { // there can be only one - [entries insertObject:entry atIndex:0]; - entriesByTitle[entry.title] = entry; - _dirty = YES; + [self.entries insertObject:entry atIndex:0]; + self.entriesByTitle[entry.title] = entry; + self.dirty = YES; } } - (void)removeEntry:(MWKSavedPageEntry*)entry { - [entries removeObject:entry]; - [entriesByTitle removeObjectForKey:entry.title]; - _dirty = YES; + [self.entries removeObject:entry]; + [self.entriesByTitle removeObjectForKey:entry.title]; + self.dirty = YES; } - (void)removeAllEntries { - [entries removeAllObjects]; - [entriesByTitle removeAllObjects]; - _dirty = YES; + [self.entries removeAllObjects]; + [self.entriesByTitle removeAllObjects]; + self.dirty = YES; } #pragma mark - data i/o methods @@ -63,8 +68,8 @@ - (instancetype)init { self = [super init]; if (self) { - entries = [[NSMutableArray alloc] init]; - entriesByTitle = [[NSMutableDictionary alloc] init]; + self.entries = [[NSMutableArray alloc] init]; + self.entriesByTitle = [[NSMutableDictionary alloc] init]; } return self; } @@ -75,10 +80,10 @@ NSArray* array = dict[@"entries"]; for (NSDictionary* entryDict in array) { MWKSavedPageEntry* entry = [[MWKSavedPageEntry alloc] initWithDict:entryDict]; - [entries addObject:entry]; - entriesByTitle[entry.title] = entry; + [self.entries addObject:entry]; + self.entriesByTitle[entry.title] = entry; } - _dirty = NO; + self.dirty = NO; } return self; } @@ -86,18 +91,18 @@ - (id)dataExport { NSMutableArray* array = [[NSMutableArray alloc] init]; - for (MWKSavedPageEntry* entry in entries) { + for (MWKSavedPageEntry* entry in self.entries) { [array addObject:[entry dataExport]]; } - _dirty = NO; + self.dirty = NO; return @{@"entries": [NSArray arrayWithArray:array]}; } - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state objects:(__unsafe_unretained id [])stackbuf count:(NSUInteger)len { - return [entries countByEnumeratingWithState:state objects:stackbuf count:len]; + return [self.entries countByEnumeratingWithState:state objects:stackbuf count:len]; } @end diff --git a/MediaWikiKit/MediaWikiKit/MWKSection.h b/MediaWikiKit/MediaWikiKit/MWKSection.h index 46484a9..e1bcdb9 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSection.h +++ b/MediaWikiKit/MediaWikiKit/MWKSection.h @@ -17,21 +17,21 @@ @interface MWKSection : MWKSiteDataObject -@property (readonly) MWKTitle* title; -@property (readonly) MWKArticle* article; +@property (readonly, strong, nonatomic) MWKTitle* title; +@property (readonly, weak, nonatomic) MWKArticle* article; -@property (readonly) NSNumber* toclevel; // optional -@property (readonly) NSNumber* level; // optional; string in JSON, but seems to be number-safe? -@property (readonly) NSString* line; // optional; HTML -@property (readonly) NSString* number; // optional; can be "1.2.3" -@property (readonly) NSString* index; // optional; can be "T-3" for transcluded sections -@property (readonly) MWKTitle* fromtitle; // optional -@property (readonly) NSString* anchor; // optional -@property (readonly) int sectionId; // required; -> id -@property (readonly) BOOL references; // optional; marked by presence of key with empty string in JSON +@property (readonly, copy, nonatomic) NSNumber* toclevel; // optional +@property (readonly, copy, nonatomic) NSNumber* level; // optional; string in JSON, but seems to be number-safe? +@property (readonly, copy, nonatomic) NSString* line; // optional; HTML +@property (readonly, copy, nonatomic) NSString* number; // optional; can be "1.2.3" +@property (readonly, copy, nonatomic) NSString* index; // optional; can be "T-3" for transcluded sections +@property (readonly, strong, nonatomic) MWKTitle* fromtitle; // optional +@property (readonly, copy, nonatomic) NSString* anchor; // optional +@property (readonly, assign, nonatomic) int sectionId; // required; -> id +@property (readonly, assign, nonatomic) BOOL references; // optional; marked by presence of key with empty string in JSON -@property (readonly) NSString* text; // may be nil -@property (readonly) MWKImageList* images; // ????? +@property (readonly, copy, nonatomic) NSString* text; // may be nil +@property (readonly, strong, nonatomic) MWKImageList* images; // ????? - (instancetype)initWithArticle:(MWKArticle*)article dict:(NSDictionary*)dict; diff --git a/MediaWikiKit/MediaWikiKit/MWKSection.m b/MediaWikiKit/MediaWikiKit/MWKSection.m index 30b3e47..6c7fef3 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSection.m +++ b/MediaWikiKit/MediaWikiKit/MWKSection.m @@ -8,29 +8,45 @@ #import "MediaWikiKit.h" -@implementation MWKSection { - NSString* _text; - MWKImageList* _images; -} +@interface MWKSection () + +@property (readwrite, strong, nonatomic) MWKTitle* title; +@property (readwrite, weak, nonatomic) MWKArticle* article; + +@property (readwrite, copy, nonatomic) NSNumber* toclevel; // optional +@property (readwrite, copy, nonatomic) NSNumber* level; // optional; string in JSON, but seems to be number-safe? +@property (readwrite, copy, nonatomic) NSString* line; // optional; HTML +@property (readwrite, copy, nonatomic) NSString* number; // optional; can be "1.2.3" +@property (readwrite, copy, nonatomic) NSString* index; // optional; can be "T-3" for transcluded sections +@property (readwrite, strong, nonatomic) MWKTitle* fromtitle; // optional +@property (readwrite, copy, nonatomic) NSString* anchor; // optional +@property (readwrite, assign, nonatomic) int sectionId; // required; -> id +@property (readwrite, assign, nonatomic) BOOL references; // optional; marked by presence of key with empty string in JSON + +@property (readwrite, copy, nonatomic) NSString* text; // may be nil +@property (readwrite, strong, nonatomic) MWKImageList* images; // ????? +@end + +@implementation MWKSection - (instancetype)initWithArticle:(MWKArticle*)article dict:(NSDictionary*)dict { self = [self initWithSite:article.site]; if (self) { - _article = article; - _title = article.title; + self.article = article; + self.title = article.title; - _toclevel = [self optionalNumber:@"toclevel" dict:dict]; - _level = [self optionalNumber:@"level" dict:dict]; // may be a numeric string - _line = [self optionalString:@"line" dict:dict]; - _number = [self optionalString:@"number" dict:dict]; // deceptively named, this must be a string - _index = [self optionalString:@"index" dict:dict]; // deceptively named, this must be a string - _fromtitle = [self optionalTitle:@"fromtitle" dict:dict]; - _anchor = [self optionalString:@"anchor" dict:dict]; - _sectionId = [[self requiredNumber:@"id" dict:dict] intValue]; - _references = ([self optionalString:@"references" dict:dict] != nil); + self.toclevel = [self optionalNumber:@"toclevel" dict:dict]; + self.level = [self optionalNumber:@"level" dict:dict]; // may be a numeric string + self.line = [self optionalString:@"line" dict:dict]; + self.number = [self optionalString:@"number" dict:dict]; // deceptively named, this must be a string + self.index = [self optionalString:@"index" dict:dict]; // deceptively named, this must be a string + self.fromtitle = [self optionalTitle:@"fromtitle" dict:dict]; + self.anchor = [self optionalString:@"anchor" dict:dict]; + self.sectionId = [[self requiredNumber:@"id" dict:dict] intValue]; + self.references = ([self optionalString:@"references" dict:dict] != nil); // Not present in .plist, loaded separately there - _text = [self optionalString:@"text" dict:dict]; + self.text = [self optionalString:@"text" dict:dict]; } return self; } diff --git a/MediaWikiKit/MediaWikiKit/MWKSectionList.h b/MediaWikiKit/MediaWikiKit/MWKSectionList.h index 10fccbc..fc8e276 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSectionList.h +++ b/MediaWikiKit/MediaWikiKit/MWKSectionList.h @@ -10,15 +10,30 @@ @interface MWKSectionList : MWKDataObject <NSFastEnumeration> -@property (readonly) MWKArticle* article; +/** + * Creates a section list and sets the sections to the provided array. + * + * @param article The article to load sections for + * @param sections The sections to load + * + * @return The Section List + */ +- (instancetype)initWithArticle:(MWKArticle*)article sections:(NSArray*)sections; -- (NSUInteger)count; - -- (MWKSection*)objectAtIndexedSubscript:(NSUInteger)idx; -- (void)setSections:(NSArray*)sections; - +/** + * Creates a section list and loads sections from disks + * + * @param article The article to load sections for + * + * @return The Section List + */ - (instancetype)initWithArticle:(MWKArticle*)article; +@property (readonly, weak, nonatomic) MWKArticle* article; + +- (NSUInteger) count; +- (MWKSection*)objectAtIndexedSubscript:(NSUInteger)idx; + - (void)save; @end diff --git a/MediaWikiKit/MediaWikiKit/MWKSectionList.m b/MediaWikiKit/MediaWikiKit/MWKSectionList.m index 57a184b..ebca4c0 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSectionList.m +++ b/MediaWikiKit/MediaWikiKit/MWKSectionList.m @@ -9,28 +9,39 @@ #import "MWKSectionList_Private.h" #import "MediaWikiKit.h" -@implementation MWKSectionList { - NSMutableArray* _sections; - unsigned long mutationState; -} +@interface MWKSectionList () + +@property (readwrite, weak, nonatomic) MWKArticle* article; +@property (strong, nonatomic) NSMutableArray* sections; +@property (assign, nonatomic) unsigned long mutationState; + +@end + +@implementation MWKSectionList - (NSUInteger)count { - return [_sections count]; + return [self.sections count]; } - (MWKSection*)objectAtIndexedSubscript:(NSUInteger)idx { - return _sections[idx]; + return self.sections[idx]; +} + +- (instancetype)initWithArticle:(MWKArticle*)article sections:(NSArray*)sections { + self = [self initWithArticle:article]; + if (self) { + self.sections = [sections mutableCopy]; + } + return self; } - (instancetype)initWithArticle:(MWKArticle*)article { self = [self init]; if (self) { - _article = article; - mutationState = 0; - if (_sections == nil) { - _sections = [NSMutableArray array]; - [self importSectionsFromDisk]; - } + self.article = article; + self.mutationState = 0; + self.sections = [NSMutableArray array]; + [self importSectionsFromDisk]; } return self; } @@ -63,12 +74,12 @@ } }@catch (NSException* e) { NSLog(@"Failed to import sections at path %@, leaving list empty.", path); - [_sections removeAllObjects]; + [self.sections removeAllObjects]; } } - (void)readAndInsertSection:(int)sectionId { - _sections[sectionId] = [self.article.dataStore sectionWithId:sectionId article:self.article]; + self.sections[sectionId] = [self.article.dataStore sectionWithId:sectionId article:self.article]; } - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state @@ -84,14 +95,9 @@ state->state += count; state->itemsPtr = stackbuf; - state->mutationsPtr = &mutationState; + state->mutationsPtr = &_mutationState; return count; -} - -- (void)setSections:(NSArray*)sections; -{ - _sections = [sections mutableCopy]; } - (void)save { diff --git a/MediaWikiKit/MediaWikiKit/MWKSite.h b/MediaWikiKit/MediaWikiKit/MWKSite.h index 647dfc3..f57e3b3 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSite.h +++ b/MediaWikiKit/MediaWikiKit/MWKSite.h @@ -11,8 +11,8 @@ @interface MWKSite : NSObject -@property (readonly) NSString* domain; -@property (readonly) NSString* language; +@property (readonly, copy, nonatomic) NSString* domain; +@property (readonly, copy, nonatomic) NSString* language; - (instancetype)initWithDomain:(NSString*)domain language:(NSString*)language; diff --git a/MediaWikiKit/MediaWikiKit/MWKSite.m b/MediaWikiKit/MediaWikiKit/MWKSite.m index ce2dfdc..aa33a74 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSite.m +++ b/MediaWikiKit/MediaWikiKit/MWKSite.m @@ -4,18 +4,41 @@ #import "MediaWikiKit.h" #import "WikipediaAppUtils.h" +@interface MWKSite () + +@property (readwrite, copy, nonatomic) NSString* domain; +@property (readwrite, copy, nonatomic) NSString* language; + +@end + @implementation MWKSite + +#pragma mark - Setup + ++ (MWKSite*)siteWithDomain:(NSString*)domain language:(NSString*)language { + static NSMutableDictionary* cachedSites = nil; + if (cachedSites == nil) { + cachedSites = [[NSMutableDictionary alloc] init]; + } + NSString* key = [NSString stringWithFormat:@"%@:%@", domain, language]; + MWKSite* site = cachedSites[key]; + if (site == nil) { + site = [[MWKSite alloc] initWithDomain:domain language:language]; + cachedSites[key] = site; + } + return site; +} - (instancetype)initWithDomain:(NSString*)domain language:(NSString*)language { self = [super init]; if (self) { - _domain = [domain copy]; - _language = [language copy]; + self.domain = domain; + self.language = language; } return self; } -#pragma mark - Title methods +#pragma mark - Title Helpers - (MWKTitle*)titleWithString:(NSString*)string { return [MWKTitle titleWithString:string site:self]; @@ -33,7 +56,7 @@ } } -#pragma mark - NSObject methods +#pragma mark - NSObject - (BOOL)isEqual:(id)object { if (object == nil) { @@ -43,23 +66,6 @@ } else { return NO; } -} - -#pragma mark - class methods - -/// !!!: make this thread safe and test for deadlocks -+ (MWKSite*)siteWithDomain:(NSString*)domain language:(NSString*)language { - static NSMutableDictionary* cachedSites = nil; - if (cachedSites == nil) { - cachedSites = [[NSMutableDictionary alloc] init]; - } - NSString* key = [NSString stringWithFormat:@"%@:%@", domain, language]; - MWKSite* site = cachedSites[key]; - if (site == nil) { - site = [[MWKSite alloc] initWithDomain:domain language:language]; - cachedSites[key] = site; - } - return site; } - (BOOL)isEqualToSite:(MWKSite*)other { diff --git a/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.h b/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.h index c42c063..bd9c367 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.h +++ b/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.h @@ -14,7 +14,7 @@ @interface MWKSiteDataObject : MWKDataObject -@property (readonly) MWKSite* site; +@property (readonly, strong, nonatomic) MWKSite* site; - (instancetype)initWithSite:(MWKSite*)site; diff --git a/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.m b/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.m index 3654f0b..659f185 100644 --- a/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.m +++ b/MediaWikiKit/MediaWikiKit/MWKSiteDataObject.m @@ -8,12 +8,18 @@ #import "MediaWikiKit.h" +@interface MWKSiteDataObject () + +@property (readwrite, strong, nonatomic) MWKSite* site; + +@end + @implementation MWKSiteDataObject - (instancetype)initWithSite:(MWKSite*)site { self = [self init]; if (self) { - _site = site; + self.site = site; } return self; } diff --git a/MediaWikiKit/MediaWikiKit/MWKTitle.h b/MediaWikiKit/MediaWikiKit/MWKTitle.h index 31a3542..05f6a3a 100644 --- a/MediaWikiKit/MediaWikiKit/MWKTitle.h +++ b/MediaWikiKit/MediaWikiKit/MWKTitle.h @@ -24,62 +24,55 @@ */ + (NSString*)normalize:(NSString*)str; - /** * The site this title belongs to */ -@property (readonly) MWKSite* site; - -/** - * Normalized namespace (decoded, no underscores) - * Warning: not implemented yet - */ -@property (readonly) NSString* namespace; +@property (readonly, strong, nonatomic) MWKSite* site; /** * Normalized title component only (decoded, no underscores) */ -@property (readonly) NSString* text; +@property (readonly, copy, nonatomic) NSString* text; /** * Fragment (component after the '#') * Warning: fragment may be nil! */ -@property (readonly) NSString* fragment; +@property (readonly, copy, nonatomic) NSString* fragment; /** * Full text-normalized namespace+title * Decoded, with spaces */ -@property (readonly) NSString* prefixedText; +@property (readonly, copy, nonatomic) NSString* prefixedText; /** * Full DB-normalized namespace+title * Decoded, with underscores */ -@property (readonly) NSString* prefixedDBKey; +@property (readonly, copy, nonatomic) NSString* prefixedDBKey; /** * Full URL-normalized namespace+title * Encoded, with underscores */ -@property (readonly) NSString* prefixedURL; +@property (readonly, copy, nonatomic) NSString* prefixedURL; /** * URL-normalized fragment, including the # if applicable * Always returns a string, may be empty string. */ -@property (readonly) NSString* fragmentForURL; +@property (readonly, copy, nonatomic) NSString* fragmentForURL; /** * Absolute URL to mobile view of this article */ -@property (readonly) NSURL* mobileURL; +@property (readonly, copy, nonatomic) NSURL* mobileURL; /** * Absolute URL to desktop view of this article */ -@property (readonly) NSURL* desktopURL; +@property (readonly, copy, nonatomic) NSURL* desktopURL; @end diff --git a/MediaWikiKit/MediaWikiKit/MWKTitle.m b/MediaWikiKit/MediaWikiKit/MWKTitle.m index a30f647..6e05c71 100644 --- a/MediaWikiKit/MediaWikiKit/MWKTitle.m +++ b/MediaWikiKit/MediaWikiKit/MWKTitle.m @@ -3,6 +3,21 @@ #import "MediaWikiKit.h" +@interface MWKTitle () + +@property (readwrite, strong, nonatomic) MWKSite* site; +@property (readwrite, copy, nonatomic) NSString* text; +@property (readwrite, copy, nonatomic) NSString* fragment; +@property (readwrite, copy, nonatomic) NSString* prefixedText; +@property (readwrite, copy, nonatomic) NSString* prefixedDBKey; +@property (readwrite, copy, nonatomic) NSString* prefixedURL; +@property (readwrite, copy, nonatomic) NSString* fragmentForURL; +@property (readwrite, copy, nonatomic) NSURL* mobileURL; +@property (readwrite, copy, nonatomic) NSURL* desktopURL; + + +@end + @implementation MWKTitle #pragma mark - Class methods @@ -21,13 +36,11 @@ - (instancetype)initWithString:(NSString*)str site:(MWKSite*)site { self = [self init]; if (self) { - _site = site; + self.site = site; NSArray* bits = [str componentsSeparatedByString:@"#"]; - _text = [MWKTitle normalize:bits[0]]; + self.text = [MWKTitle normalize:bits[0]]; if (bits.count > 1) { - _fragment = bits[1]; - } else { - _fragment = nil; + self.fragment = bits[1]; } } return self; @@ -37,6 +50,7 @@ - (NSString*)namespace { // @todo implement namespace detection and normalization + // rename the property from a reserved language name // doing this right requires some site info return nil; } diff --git a/MediaWikiKit/MediaWikiKit/MWKUser.h b/MediaWikiKit/MediaWikiKit/MWKUser.h index e3ad7da..7e6cc99 100644 --- a/MediaWikiKit/MediaWikiKit/MWKUser.h +++ b/MediaWikiKit/MediaWikiKit/MWKUser.h @@ -14,9 +14,9 @@ @interface MWKUser : MWKSiteDataObject -@property (readonly) bool anonymous; -@property (readonly) NSString* name; -@property (readonly) NSString* gender; // used to format UI messages on-wiki +@property (readonly, assign, nonatomic) BOOL anonymous; +@property (readonly, copy, nonatomic) NSString* name; +@property (readonly, copy, nonatomic) NSString* gender; - (instancetype)initWithSite:(MWKSite*)site data:(id)data; diff --git a/MediaWikiKit/MediaWikiKit/MWKUser.m b/MediaWikiKit/MediaWikiKit/MWKUser.m index ecb6981..04e27ab 100644 --- a/MediaWikiKit/MediaWikiKit/MWKUser.m +++ b/MediaWikiKit/MediaWikiKit/MWKUser.m @@ -8,19 +8,27 @@ #import "MediaWikiKit.h" +@interface MWKUser () + +@property (readwrite, assign, nonatomic) BOOL anonymous; +@property (readwrite, copy, nonatomic) NSString* name; +@property (readwrite, copy, nonatomic) NSString* gender; + +@end + @implementation MWKUser - (instancetype)initWithSite:(MWKSite*)site data:(id)data { self = [self initWithSite:site]; if ([data isKindOfClass:[NSNull class]]) { - _anonymous = YES; - _name = nil; - _gender = nil; + self.anonymous = YES; + self.name = nil; + self.gender = nil; } else if ([data isKindOfClass:[NSDictionary class]]) { NSDictionary* dict = (NSDictionary*)data; - _anonymous = NO; - _name = [self requiredString:@"name" dict:dict]; - _gender = [self requiredString:@"gender" dict:dict]; + self.anonymous = NO; + self.name = [self requiredString:@"name" dict:dict]; + self.gender = [self requiredString:@"gender" dict:dict]; } else { @throw [NSException exceptionWithName:@"MWKDataObjectException" reason:@"expected null or user info dict, got something else" diff --git a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h index 1b80a70..190f900 100644 --- a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h +++ b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.h @@ -18,10 +18,10 @@ @interface MWKUserDataStore : NSObject -@property (readonly) MWKDataStore* dataStore; -@property (readonly) MWKHistoryList* historyList; -@property (readonly) MWKSavedPageList* savedPageList; -@property (readonly) MWKRecentSearchList* recentSearchList; +@property (readonly, weak, nonatomic) MWKDataStore* dataStore; +@property (readonly, strong, nonatomic) MWKHistoryList* historyList; +@property (readonly, strong, nonatomic) MWKSavedPageList* savedPageList; +@property (readonly, strong, nonatomic) MWKRecentSearchList* recentSearchList; - (instancetype)initWithDataStore:(MWKDataStore*)dataStore; diff --git a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m index e4c5c84..6acfe09 100644 --- a/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m +++ b/MediaWikiKit/MediaWikiKit/MWKUserDataStore.m @@ -8,18 +8,25 @@ #import "MediaWikiKit.h" -@implementation MWKUserDataStore { - MWKHistoryList* _historyList; - MWKSavedPageList* _savedPageList; - MWKRecentSearchList* _recentSearchList; -} +@interface MWKUserDataStore () + +@property (readwrite, weak, nonatomic) MWKDataStore* dataStore; +@property (readwrite, strong, nonatomic) MWKHistoryList* historyList; +@property (readwrite, strong, nonatomic) MWKSavedPageList* savedPageList; +@property (readwrite, strong, nonatomic) MWKRecentSearchList* recentSearchList; + +@end + +@implementation MWKUserDataStore - (BOOL)save:(NSError**)error { BOOL success = YES; if (_historyList && _historyList.dirty) { - success = [self.dataStore saveHistoryList:_historyList error:error]; - NSAssert(success, @"Error saving history: %@", [*error localizedDescription]); + if (![self.dataStore saveHistoryList:_historyList error:error]) { + NSAssert(NO, @"Error saving history: %@", [*error localizedDescription]); + } + ; } if (_savedPageList && _savedPageList.dirty) { [self.dataStore saveSavedPageList:_savedPageList]; @@ -37,20 +44,15 @@ /// Clear out any currently loaded data and force it to be reloaded on next use - (void)reset { - _historyList = nil; - _savedPageList = nil; - _recentSearchList = nil; + self.historyList = nil; + self.savedPageList = nil; + self.recentSearchList = nil; } - (instancetype)initWithDataStore:(MWKDataStore*)dataStore { self = [self init]; if (self) { - _dataStore = dataStore; - - // Load these on demand - _historyList = nil; - _savedPageList = nil; - _recentSearchList = nil; + self.dataStore = dataStore; } return self; } diff --git a/Wikipedia/Data/SchemaConverter.h b/Wikipedia/Data/SchemaConverter.h index dfad96e..c274f30 100644 --- a/Wikipedia/Data/SchemaConverter.h +++ b/Wikipedia/Data/SchemaConverter.h @@ -14,9 +14,9 @@ @interface SchemaConverter : NSObject <OldDataSchemaDelegate> -@property OldDataSchemaMigrator* schema; -@property MWKDataStore* dataStore; -@property MWKUserDataStore* userDataStore; +@property (nonatomic, strong) OldDataSchemaMigrator* schema; +@property (nonatomic, strong) MWKDataStore* dataStore; +@property (nonatomic, strong) MWKUserDataStore* userDataStore; - (instancetype)initWithDataStore:(MWKDataStore*)dataStore; diff --git a/Wikipedia/Session/SessionSingleton.m b/Wikipedia/Session/SessionSingleton.m index aaecd3c..84cd049 100644 --- a/Wikipedia/Session/SessionSingleton.m +++ b/Wikipedia/Session/SessionSingleton.m @@ -65,8 +65,8 @@ self.zeroConfigState = [[ZeroConfigState alloc] init]; self.zeroConfigState.disposition = false; - _dataStore = dataStore; - _userDataStore = dataStore.userDataStore; + self.dataStore = dataStore; + self.userDataStore = [dataStore userDataStore]; _currentArticleSite = [self lastKnownSite]; -- To view, visit https://gerrit.wikimedia.org/r/211716 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I4938141e8cdfc76241bafd220d7362c32b55be6c Gerrit-PatchSet: 3 Gerrit-Project: apps/ios/wikipedia Gerrit-Branch: master Gerrit-Owner: Fjalapeno <cfl...@wikimedia.org> Gerrit-Reviewer: Bgerstle <bgers...@wikimedia.org> Gerrit-Reviewer: Mhurd <mh...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits