Bgerstle has uploaded a new change for review.
https://gerrit.wikimedia.org/r/226644
Change subject: fix crash when saving empty/nil title
......................................................................
fix crash when saving empty/nil title
Bug: T106028
Change-Id: I8f52107717fd301c89bdd0e3022e53d1862fbcd2
---
M MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m
M MediaWikiKit/MediaWikiKit/MWKSavedPageList.h
M MediaWikiKit/MediaWikiKit/MWKSavedPageList.m
M MediaWikiKit/MediaWikiKit/MediaWikiKit.h
A MediaWikiKit/MediaWikiKit/NSError+MWKErrors.h
A MediaWikiKit/MediaWikiKit/NSError+MWKErrors.m
A MediaWikiKit/MediaWikiKitTests/MWKSavedPageListTests.m
M Wikipedia.xcodeproj/project.pbxproj
M Wikipedia/EventLogging/SavedPagesFunnel.h
M Wikipedia/EventLogging/SavedPagesFunnel.m
M Wikipedia/Global.h
M Wikipedia/Session/SessionSingleton.h
M Wikipedia/Session/SessionSingleton.m
M Wikipedia/View Controllers/WebView/WebViewController.m
A Wikipedia/mw-utils/WMFOutParamUtils.h
A WikipediaUnitTests/WMFSafeAssignTests.m
16 files changed, 284 insertions(+), 24 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/ios/wikipedia
refs/changes/44/226644/1
diff --git a/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m
b/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m
index 9bfa6e4..72b26b8 100644
--- a/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m
+++ b/MediaWikiKit/MediaWikiKit/MWKSavedPageEntry.m
@@ -47,4 +47,10 @@
return [NSDictionary dictionaryWithDictionary:dict];
}
+WMF_SYNTHESIZE_IS_EQUAL(MWKSavedPageEntry, isEqualToSavedEntry:)
+
+- (BOOL)isEqualToSavedEntry:(MWKSavedPageEntry*)rhs {
+ return WMF_RHS_PROP_EQUAL(title, isEqualToTitle:);
+}
+
@end
diff --git a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h
b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h
index fda336a..fafd391 100644
--- a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h
+++ b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.h
@@ -22,6 +22,16 @@
- (MWKSavedPageEntry*)entryForTitle:(MWKTitle*)title;
- (BOOL)isSaved:(MWKTitle*)title;
+/**
+ * Toggle the save state for `title`.
+ *
+ * @param title Title to toggle state for, either saving or un-saving it.
+ * @param error Out-param of any error that occurred while toggling save state
and saving.
+ *
+ * @return The new saved state for `title` (i.e. `YES` if saved, `NO` if not).
+ */
+- (BOOL)toggleSaveStateForTitle:(MWKTitle*)title error:(NSError**)error;
+
/// Add a new entry to the saved page list!
- (void)addEntry:(MWKSavedPageEntry*)entry;
/// Remove one.
diff --git a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m
b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m
index 5aeafef..bdce33c 100644
--- a/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m
+++ b/MediaWikiKit/MediaWikiKit/MWKSavedPageList.m
@@ -7,6 +7,7 @@
//
#import "MediaWikiKit.h"
+#import "NSError+MWKErrors.h"
@interface MWKSavedPageList ()
@@ -18,6 +19,21 @@
@implementation MWKSavedPageList
+- (BOOL)toggleSaveStateForTitle:(MWKTitle*)title error:(NSError*
__autoreleasing*)error {
+ if (!title.text.length) {
+ WMFSafeAssign(error, [NSError wmf_emptyTitleError]);
+ return NO;
+ }
+ MWKSavedPageEntry* entry = [self entryForTitle:title];
+ if (!entry) {
+ [self addEntry:[[MWKSavedPageEntry alloc] initWithTitle:title]];
+ return YES;
+ } else {
+ [self removeEntry:entry];
+ return NO;
+ }
+}
+
- (NSUInteger)length {
return [self.entries count];
}
diff --git a/MediaWikiKit/MediaWikiKit/MediaWikiKit.h
b/MediaWikiKit/MediaWikiKit/MediaWikiKit.h
index 2001f21..9072924 100644
--- a/MediaWikiKit/MediaWikiKit/MediaWikiKit.h
+++ b/MediaWikiKit/MediaWikiKit/MediaWikiKit.h
@@ -10,6 +10,7 @@
#import <Foundation/Foundation.h>
+#import "NSError+MWKErrors.h"
#import "MWKDataObject.h"
#import "MWKSiteDataObject.h"
diff --git a/MediaWikiKit/MediaWikiKit/NSError+MWKErrors.h
b/MediaWikiKit/MediaWikiKit/NSError+MWKErrors.h
new file mode 100644
index 0000000..9a2eae4
--- /dev/null
+++ b/MediaWikiKit/MediaWikiKit/NSError+MWKErrors.h
@@ -0,0 +1,23 @@
+//
+// NSError+MWKErrors.h
+// Wikipedia
+//
+// Created by Brian Gerstle on 7/23/15.
+// Copyright (c) 2015 Wikimedia Foundation. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+extern NSString* const MWKErrorDomain;
+
+typedef NS_ENUM (NSInteger, MWKErrorCode) {
+ MWKEmptyTitleError = 1
+};
+
+@interface NSError (MWKErrors)
+
++ (instancetype)wmf_emptyTitleError;
+
++ (instancetype)wmf_mwkError:(MWKErrorCode)code
userInfo:(NSDictionary*)userInfo;
+
+@end
diff --git a/MediaWikiKit/MediaWikiKit/NSError+MWKErrors.m
b/MediaWikiKit/MediaWikiKit/NSError+MWKErrors.m
new file mode 100644
index 0000000..17c5cfc
--- /dev/null
+++ b/MediaWikiKit/MediaWikiKit/NSError+MWKErrors.m
@@ -0,0 +1,25 @@
+//
+// NSError+MWKErrors.m
+// Wikipedia
+//
+// Created by Brian Gerstle on 7/23/15.
+// Copyright (c) 2015 Wikimedia Foundation. All rights reserved.
+//
+
+#import "NSError+MWKErrors.h"
+
+NSString* const MWKErrorDomain = @"MWKErrorDomain";
+
+@implementation NSError (MWKErrors)
+
++ (instancetype)wmf_emptyTitleError {
+ return [self wmf_mwkError:MWKEmptyTitleError userInfo:@{
+ NSLocalizedDescriptionKey:
MWLocalizedString(@"mwk-empty-title-error", nil)
+ }];
+}
+
++ (instancetype)wmf_mwkError:(MWKErrorCode)code
userInfo:(NSDictionary*)userInfo {
+ return [NSError errorWithDomain:MWKErrorDomain code:code
userInfo:userInfo];
+}
+
+@end
diff --git a/MediaWikiKit/MediaWikiKitTests/MWKSavedPageListTests.m
b/MediaWikiKit/MediaWikiKitTests/MWKSavedPageListTests.m
new file mode 100644
index 0000000..b59f8e6
--- /dev/null
+++ b/MediaWikiKit/MediaWikiKitTests/MWKSavedPageListTests.m
@@ -0,0 +1,67 @@
+//
+// MWKSavedPageListTests.m
+// Wikipedia
+//
+// Created by Brian Gerstle on 7/23/15.
+// Copyright (c) 2015 Wikimedia Foundation. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+#import "MWKSavedPageList.h"
+
+#define MOCKITO_SHORTHAND 1
+#import <OCMockito/OCMockito.h>
+
+@interface MWKSavedPageListTests : XCTestCase
+@property (nonatomic, strong) MWKSavedPageList* list;
+@end
+
+@implementation MWKSavedPageListTests
+
+- (void)setUp {
+ self.list = [[MWKSavedPageList alloc] init];
+}
+
+- (MWKSavedPageEntry*)entryWithTitleText:(NSString*)titleText {
+ MWKTitle* title =
+ [[MWKTitle alloc] initWithSite:[MWKSite siteWithCurrentLocale]
normalizedTitle:titleText fragment:nil];
+ return [[MWKSavedPageEntry alloc] initWithTitle:title];
+}
+
+- (void)testTogglingSavedPageReturnsNoAndRemovesFromList {
+ MWKSavedPageEntry* savedEntry = [self entryWithTitleText:@"foo"];
+ [self.list addEntry:savedEntry];
+ NSError* saveError;
+ BOOL postToggleSaveState = [self.list
toggleSaveStateForTitle:savedEntry.title error:&saveError];
+ XCTAssertNil(saveError);
+ XCTAssertFalse(postToggleSaveState);
+ XCTAssertNil([self.list entryForTitle:savedEntry.title]);
+}
+
+- (void)testToggleUnsavedPageReturnsYesAndAddsToList {
+ MWKSavedPageEntry* unsavedEntry = [self entryWithTitleText:@"foo"];
+ NSError* toggleError;
+ BOOL postToggleSaveState = [self.list
toggleSaveStateForTitle:unsavedEntry.title error:&toggleError];
+ XCTAssertNil(toggleError);
+ XCTAssertTrue(postToggleSaveState);
+ XCTAssertEqualObjects([self.list entryForTitle:unsavedEntry.title],
unsavedEntry);
+}
+
+- (void)testTogglePageWithNilTitleReturnsFalseWithError {
+ NSError* toggleError;
+ BOOL postToggleSaveState = [self.list toggleSaveStateForTitle:nil
error:&toggleError];
+ XCTAssertFalse(postToggleSaveState);
+ XCTAssertEqual(toggleError.code, MWKEmptyTitleError);
+}
+
+- (void)testTogglePageWithEmptyTitleReturnsFalseWithError {
+ MWKTitle* emptyTitle = mock([MWKTitle class]);
+ [given([emptyTitle text]) willReturn:@""];
+ NSError* toggleError;
+ BOOL postToggleSaveState = [self.list toggleSaveStateForTitle:emptyTitle
error:&toggleError];
+ XCTAssertFalse(postToggleSaveState);
+ XCTAssertEqual(toggleError.code, MWKEmptyTitleError);
+}
+
+@end
diff --git a/Wikipedia.xcodeproj/project.pbxproj
b/Wikipedia.xcodeproj/project.pbxproj
index ae8fc76..539f453 100644
--- a/Wikipedia.xcodeproj/project.pbxproj
+++ b/Wikipedia.xcodeproj/project.pbxproj
@@ -244,6 +244,9 @@
BC5FE5751B1DFF5400273BC0 /* ArticleFetcherTests.m in Sources */
= {isa = PBXBuildFile; fileRef = BC5FE5741B1DFF5400273BC0 /*
ArticleFetcherTests.m */; };
BC69C3141AB0C1FF0090B039 /* WMFImageInfoController.m in Sources
*/ = {isa = PBXBuildFile; fileRef = BC69C3131AB0C1FF0090B039 /*
WMFImageInfoController.m */; };
BC6BF4001B19213600362968 /* XCTestCase+WMFLocaleTesting.m in
Sources */ = {isa = PBXBuildFile; fileRef = BC6BF3FE1B19209900362968 /*
XCTestCase+WMFLocaleTesting.m */; };
+ BC725EC71B6111E600E0A64C /* NSError+MWKErrors.m in Sources */ =
{isa = PBXBuildFile; fileRef = BC725EC61B6111E600E0A64C /* NSError+MWKErrors.m
*/; };
+ BC725ECA1B617E1A00E0A64C /* WMFSafeAssignTests.m in Sources */
= {isa = PBXBuildFile; fileRef = BC725EC91B617E1A00E0A64C /*
WMFSafeAssignTests.m */; };
+ BC725ECC1B6182C800E0A64C /* MWKSavedPageListTests.m in Sources
*/ = {isa = PBXBuildFile; fileRef = BC725ECB1B6182C800E0A64C /*
MWKSavedPageListTests.m */; };
BC7DFCD61AA4E5FE000035C3 /* WMFImageURLParsing.m in Sources */
= {isa = PBXBuildFile; fileRef = BC7DFCD51AA4E5FE000035C3 /*
WMFImageURLParsing.m */; };
BC7E4A521B34B53E00EECD8B /* MWKLanguageLinkControllerTests.m in
Sources */ = {isa = PBXBuildFile; fileRef = BC7E4A511B34B53E00EECD8B /*
MWKLanguageLinkControllerTests.m */; };
BC86B9361A92966B00B4C039 /*
AFHTTPRequestOperationManager+UniqueRequests.m in Sources */ = {isa =
PBXBuildFile; fileRef = BC86B9351A92966B00B4C039 /*
AFHTTPRequestOperationManager+UniqueRequests.m */; };
@@ -796,6 +799,11 @@
BC6BF3FD1B19209900362968 /* XCTestCase+WMFLocaleTesting.h */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h;
path = "XCTestCase+WMFLocaleTesting.h"; sourceTree = "<group>"; };
BC6BF3FE1B19209900362968 /* XCTestCase+WMFLocaleTesting.m */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.c.objc; path = "XCTestCase+WMFLocaleTesting.m"; sourceTree =
"<group>"; };
BC6FEAE01A9B7EFD00A1D890 /* WMFCodingStyle.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= WMFCodingStyle.m; sourceTree = "<group>"; };
+ BC725EC51B6111E600E0A64C /* NSError+MWKErrors.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
"NSError+MWKErrors.h"; sourceTree = "<group>"; };
+ BC725EC61B6111E600E0A64C /* NSError+MWKErrors.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= "NSError+MWKErrors.m"; sourceTree = "<group>"; };
+ BC725EC81B61255400E0A64C /* WMFOutParamUtils.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path =
WMFOutParamUtils.h; sourceTree = "<group>"; };
+ BC725EC91B617E1A00E0A64C /* WMFSafeAssignTests.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= WMFSafeAssignTests.m; sourceTree = "<group>"; };
+ BC725ECB1B6182C800E0A64C /* MWKSavedPageListTests.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= MWKSavedPageListTests.m; sourceTree = "<group>"; };
BC7A4A231B17B3510003E73E /* NSObjectUtilities.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path =
NSObjectUtilities.h; sourceTree = "<group>"; };
BC7ACB621AB34C9C00791497 /* WMFAsyncTestCase.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name =
WMFAsyncTestCase.h; path = ../WMFAsyncTestCase.h; sourceTree = "<group>"; };
BC7ACB631AB34C9C00791497 /* WMFAsyncTestCase.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name
= WMFAsyncTestCase.m; path = ../WMFAsyncTestCase.m; sourceTree = "<group>"; };
@@ -2149,6 +2157,7 @@
BC092BA61B19189100093C59 /*
MWKSiteInfoFetcherTests.m */,
BC7E4A511B34B53E00EECD8B /*
MWKLanguageLinkControllerTests.m */,
BC905BCF1B60391F0010227E /*
MWKLanguageLinkFetcherTests.m */,
+ BC725EC91B617E1A00E0A64C /*
WMFSafeAssignTests.m */,
);
name = Tests;
path = WikipediaUnitTests;
@@ -2291,6 +2300,8 @@
BCB6697C1A83F6C300C7B1FE /* Metadata classes */,
BCB669951A83F6C300C7B1FE /* Data classes */,
BCB669A21A83F6C300C7B1FE /* Data i/o */,
+ BC725EC51B6111E600E0A64C /* NSError+MWKErrors.h
*/,
+ BC725EC61B6111E600E0A64C /* NSError+MWKErrors.m
*/,
);
name = MediaWikiKit;
path = MediaWikiKit/MediaWikiKit;
@@ -2316,6 +2327,7 @@
BCFE02691B41ABB5003752B7 /*
MWKHistoryListCorruptDataTests.m */,
BCFE026E1B41B482003752B7 /*
MWKSavedPageListCorruptDataTests.m */,
BCFE02771B41FA12003752B7 /*
MWKHistoryListPerformanceTests.m */,
+ BC725ECB1B6182C800E0A64C /*
MWKSavedPageListTests.m */,
);
name = MediaWikiKitTests;
path = ../MediaWikiKit/MediaWikiKitTests;
@@ -2444,6 +2456,7 @@
BC7A4A231B17B3510003E73E /* NSObjectUtilities.h
*/,
BC092B971B18E8AF00093C59 /*
NSString+WMFPageUtilities.h */,
BC092B951B18E89200093C59 /*
NSString+WMFPageUtilities.m */,
+ BC725EC81B61255400E0A64C /* WMFOutParamUtils.h
*/,
);
path = "mw-utils";
sourceTree = "<group>";
@@ -2985,6 +2998,7 @@
BC0FED731AAA026C002488D7 /*
NSMutableDictionary+MaybeSetTests.m in Sources */,
048830D31AB775E3005BF3A1 /*
UIScrollView+WMFScrollsToTop.m in Sources */,
BC0FED6E1AAA0268002488D7 /* MWKImageListTests.m
in Sources */,
+ BC725ECC1B6182C800E0A64C /*
MWKSavedPageListTests.m in Sources */,
BC23759E1AB8928600B0BAA8 /*
WMFDateFormatterTests.m in Sources */,
BC0FED771AAA026C002488D7 /*
WMFImageURLParsingTests.m in Sources */,
BCEC778F1AC9AEC800D9DDA5 /*
MWKImage+AssociationTestUtils.m in Sources */,
@@ -3023,6 +3037,7 @@
04F122671ACB818F002FC3B5 /*
NSString+FormattedAttributedString.m in Sources */,
BC0FED711AAA026C002488D7 /*
WMFJoinedPropertyParametersTests.m in Sources */,
BC0FED6A1AAA0268002488D7 /*
MWKDataStorePathTests.m in Sources */,
+ BC725ECA1B617E1A00E0A64C /*
WMFSafeAssignTests.m in Sources */,
BC0FED761AAA026C002488D7 /*
NSString+WMFHTMLParsingTests.m in Sources */,
BCA676571AC05FE200A16160 /*
XCTestCase+WMFBundleConvenience.m in Sources */,
BC0FED671AAA0268002488D7 /* MWKTitleTests.m in
Sources */,
@@ -3093,6 +3108,7 @@
043F18E518D9691D00D8489A /*
UINavigationController+TopActionSheet.m in Sources */,
044396231A3D33030081557D /*
UICollectionViewCell+DynamicCellHeight.m in Sources */,
04414DDF1A1420EB00A41B4E /*
WikiDataShortDescriptionFetcher.m in Sources */,
+ BC725EC71B6111E600E0A64C /* NSError+MWKErrors.m
in Sources */,
0EFB0F1F1B31EE2D00D05C08 /* DiscoveryContext.m
in Sources */,
04D686F61AB2949C0009B44A /* MenuLabel.m in
Sources */,
04D308281998A8AA0034F106 /*
NearbyThumbnailView.m in Sources */,
diff --git a/Wikipedia/EventLogging/SavedPagesFunnel.h
b/Wikipedia/EventLogging/SavedPagesFunnel.h
index b370f62..cf5d970 100644
--- a/Wikipedia/EventLogging/SavedPagesFunnel.h
+++ b/Wikipedia/EventLogging/SavedPagesFunnel.h
@@ -12,7 +12,8 @@
@property NSString* appInstallId;
-- (id)init;
++ (void)logStateChange:(BOOL)didSave;
+
/**
* Log the saving of a new page to the saved set.
diff --git a/Wikipedia/EventLogging/SavedPagesFunnel.m
b/Wikipedia/EventLogging/SavedPagesFunnel.m
index 21a1a74..612e899 100644
--- a/Wikipedia/EventLogging/SavedPagesFunnel.m
+++ b/Wikipedia/EventLogging/SavedPagesFunnel.m
@@ -13,7 +13,7 @@
@implementation SavedPagesFunnel
-- (id)init {
+- (instancetype)init {
// http://meta.wikimedia.org/wiki/Schema:MobileWikiAppSavedPages
self = [super initWithSchema:@"MobileWikiAppSavedPages" version:10375480];
if (self) {
@@ -22,6 +22,15 @@
return self;
}
++ (void)logStateChange:(BOOL)didSave {
+ SavedPagesFunnel* funnel = [self new];
+ if (didSave) {
+ [funnel logSaveNew];
+ } else {
+ [funnel logDelete];
+ }
+}
+
- (void)logSaveNew {
[self log:@{@"action": @"savenew"}];
}
diff --git a/Wikipedia/Global.h b/Wikipedia/Global.h
index b6bca8a..e1df3f1 100644
--- a/Wikipedia/Global.h
+++ b/Wikipedia/Global.h
@@ -10,6 +10,7 @@
#import "WMFGCDHelpers.h"
#import "NSObjectUtilities.h"
+#import "WMFOutParamUtils.h"
#import "RootViewController.h"
#import "CenterNavController.h"
diff --git a/Wikipedia/Session/SessionSingleton.h
b/Wikipedia/Session/SessionSingleton.h
index aa86bb7..2afbaef 100644
--- a/Wikipedia/Session/SessionSingleton.h
+++ b/Wikipedia/Session/SessionSingleton.h
@@ -85,4 +85,12 @@
// file is known to be associated with an article title.
@property (strong, nonatomic) NSMutableDictionary* titleToTempDirThumbURLMap;
+/**
+ * Toggle save state of the current article, if there is one.
+ * @param error Out-param of any error that occurred while toggling save state
and saving.
+ * @return The new saved state of the currentArticle (i.e. `YES` if saved,
`NO` if not).
+ * @see -[MWKSavedPageList toggleSaveStateForTitle:error:]
+ */
+- (BOOL)toggleSaveStateForCurrentArticle:(NSError* __autoreleasing*)error;
+
@end
diff --git a/Wikipedia/Session/SessionSingleton.m
b/Wikipedia/Session/SessionSingleton.m
index e5cf3a7..ca63426 100644
--- a/Wikipedia/Session/SessionSingleton.m
+++ b/Wikipedia/Session/SessionSingleton.m
@@ -180,4 +180,23 @@
[[QueuesSingleton sharedInstance] reset];
}
+#pragma mark - Save
+
+- (BOOL)toggleSaveStateForCurrentArticle:(NSError* __autoreleasing*)error {
+ NSError* toggleSaveError;
+ BOOL didSave = [self.userDataStore.savedPageList
toggleSaveStateForTitle:self.currentArticle.title
+
error:&toggleSaveError];
+ if (toggleSaveError) {
+ WMFSafeAssign(error, toggleSaveError);
+ return NO;
+ }
+ [self.userDataStore save:&toggleSaveError];
+ if (toggleSaveError) {
+ WMFSafeAssign(error, toggleSaveError);
+ return NO;
+ }
+ [SavedPagesFunnel logStateChange:didSave];
+ return didSave;
+}
+
@end
diff --git a/Wikipedia/View Controllers/WebView/WebViewController.m
b/Wikipedia/View Controllers/WebView/WebViewController.m
index da8259f..efbe623 100644
--- a/Wikipedia/View Controllers/WebView/WebViewController.m
+++ b/Wikipedia/View Controllers/WebView/WebViewController.m
@@ -966,34 +966,19 @@
#pragma Saved Pages
- (void)saveCurrentPage {
- MWKTitle* title = self.session.currentArticle.title;
- MWKUserDataStore* store = self.session.userDataStore;
- MWKSavedPageList* list = store.savedPageList;
- MWKSavedPageEntry* entry = [list entryForTitle:title];
-
- SavedPagesFunnel* funnel = [[SavedPagesFunnel alloc] init];
-
- if (entry == nil) {
- // Show alert.
- [self showPageSavedAlertMessageForTitle:title.text];
-
- // Actually perform the save.
- entry = [[MWKSavedPageEntry alloc] initWithTitle:title];
- [list addEntry:entry];
-
- [store save];
- [funnel logSaveNew];
+ NSError* error;
+ BOOL didSave = [self.session toggleSaveStateForCurrentArticle:&error];
+ if (error) {
+ [self showAlert:error.localizedDescription type:ALERT_TYPE_TOP
duration:2.f];
+ } else if (didSave) {
+ [self
showPageSavedAlertMessageForTitle:self.session.currentArticle.title.text];
} else {
- // Unsave!
- [list removeEntry:entry];
- [store save];
-
[self fadeAlert];
- [funnel logDelete];
}
}
- (void)showPageSavedAlertMessageForTitle:(NSString*)title {
+ NSParameterAssert(title.length);
// First show saved message.
NSString* savedMessage = MWLocalizedString(@"share-menu-page-saved", nil);
diff --git a/Wikipedia/mw-utils/WMFOutParamUtils.h
b/Wikipedia/mw-utils/WMFOutParamUtils.h
new file mode 100644
index 0000000..73d42c3
--- /dev/null
+++ b/Wikipedia/mw-utils/WMFOutParamUtils.h
@@ -0,0 +1,36 @@
+//
+// WMFOutParamUtils.h
+// Wikipedia
+//
+// Created by Brian Gerstle on 7/23/15.
+// Copyright (c) 2015 Wikimedia Foundation. All rights reserved.
+//
+
+#ifndef Wikipedia_WMFOutParamUtils_h
+#define Wikipedia_WMFOutParamUtils_h
+
+/**
+ * Safely assign a value to an outParam (or any other double pointer).
+ *
+ * For example:
+ @code
+ - (BOOL)myMethod:(NSError**)outErr {
+ NSError* error = [self somethingDangerous];
+ if (error) {
+ WMFSafeAssign(outErr, error);
+ return NO;
+ }
+ return YES;
+ }
+ @endcode
+ *
+ * @note This needs to be a macro due to problems casting between ObjC & C
indirect pointers.
+ */
+#define WMFSafeAssign(outParam, value) \
+ do { \
+ if (outParam != NULL) { \
+ *(outParam) = (value); \
+ } \
+ } while (0)
+
+#endif
diff --git a/WikipediaUnitTests/WMFSafeAssignTests.m
b/WikipediaUnitTests/WMFSafeAssignTests.m
new file mode 100644
index 0000000..173339e
--- /dev/null
+++ b/WikipediaUnitTests/WMFSafeAssignTests.m
@@ -0,0 +1,37 @@
+//
+// WMFSafeAssignTests.m
+// Wikipedia
+//
+// Created by Brian Gerstle on 7/23/15.
+// Copyright (c) 2015 Wikimedia Foundation. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+#import "WMFOutParamUtils.h"
+
+@interface WMFSafeAssignTests : XCTestCase
+
+@end
+
+@implementation WMFSafeAssignTests
+
+- (void)assignValue:(id)value toOutParam:(NSObject**)outObj {
+ WMFSafeAssign(outObj, value);
+}
+
+- (void)testAssigningNilToNil {
+ XCTAssertNoThrow([self assignValue:nil toOutParam:nil]);
+}
+
+- (void)testAssigningValueToRef {
+ id outValue;
+ XCTAssertNoThrow([self assignValue:@1 toOutParam:&outValue]);
+ XCTAssertEqualObjects(@1, outValue);
+}
+
+- (void)testAssigningValueToNil {
+ XCTAssertNoThrow([self assignValue:@1 toOutParam:nil]);
+}
+
+@end
--
To view, visit https://gerrit.wikimedia.org/r/226644
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8f52107717fd301c89bdd0e3022e53d1862fbcd2
Gerrit-PatchSet: 1
Gerrit-Project: apps/ios/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Bgerstle <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits