diff --git a/CHANGELOG.md b/CHANGELOG.md index 471fc2bb..928ea9b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ _None._ ### Breaking Changes -_None._ +- Re-implement a few reader model types in Swift. [#556] ### New Features diff --git a/WordPressKit.xcodeproj/project.pbxproj b/WordPressKit.xcodeproj/project.pbxproj index 76b36481..93fec4ce 100644 --- a/WordPressKit.xcodeproj/project.pbxproj +++ b/WordPressKit.xcodeproj/project.pbxproj @@ -124,6 +124,9 @@ 46ABD0EA262EEE0400C7FF24 /* AppTransportSecuritySettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46ABD0E9262EEE0400C7FF24 /* AppTransportSecuritySettingsTests.swift */; }; 4A1DEF44293051BC00322608 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A1DEF43293051BC00322608 /* LoggingTests.swift */; }; 4A1DEF46293051C600322608 /* LoggingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A1DEF45293051C600322608 /* LoggingTests.m */; }; + 4A68E3DD294070A7004AC3DC /* RemoteReaderSite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A68E3DC294070A7004AC3DC /* RemoteReaderSite.swift */; }; + 4A68E3DF29407100004AC3DC /* RemoteReaderTopic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A68E3DE29407100004AC3DC /* RemoteReaderTopic.swift */; }; + 4A68E3E1294076C1004AC3DC /* RemoteReaderSiteInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A68E3E0294076C1004AC3DC /* RemoteReaderSiteInfo.swift */; }; 4A68E3CD29404181004AC3DC /* RemoteBlog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A68E3CC29404181004AC3DC /* RemoteBlog.swift */; }; 4A68E3CF29404289004AC3DC /* RemoteBlogOptionsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A68E3CE29404289004AC3DC /* RemoteBlogOptionsHelper.swift */; }; 4A68E3D329406AA0004AC3DC /* RemoteMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A68E3D029406AA0004AC3DC /* RemoteMenu.swift */; }; @@ -200,12 +203,6 @@ 7430C9A81F1927180051B8E6 /* ReaderTopicServiceRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9A21F1927180051B8E6 /* ReaderTopicServiceRemote.m */; }; 7430C9B11F1927C50051B8E6 /* RemoteReaderPost.h in Headers */ = {isa = PBXBuildFile; fileRef = 7430C9A91F1927C50051B8E6 /* RemoteReaderPost.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7430C9B21F1927C50051B8E6 /* RemoteReaderPost.m in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9AA1F1927C50051B8E6 /* RemoteReaderPost.m */; }; - 7430C9B31F1927C50051B8E6 /* RemoteReaderSite.h in Headers */ = {isa = PBXBuildFile; fileRef = 7430C9AB1F1927C50051B8E6 /* RemoteReaderSite.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7430C9B41F1927C50051B8E6 /* RemoteReaderSite.m in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9AC1F1927C50051B8E6 /* RemoteReaderSite.m */; }; - 7430C9B51F1927C50051B8E6 /* RemoteReaderSiteInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7430C9AD1F1927C50051B8E6 /* RemoteReaderSiteInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7430C9B61F1927C50051B8E6 /* RemoteReaderSiteInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9AE1F1927C50051B8E6 /* RemoteReaderSiteInfo.m */; }; - 7430C9B71F1927C50051B8E6 /* RemoteReaderTopic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7430C9AF1F1927C50051B8E6 /* RemoteReaderTopic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7430C9B81F1927C50051B8E6 /* RemoteReaderTopic.m in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9B01F1927C50051B8E6 /* RemoteReaderTopic.m */; }; 7430C9BC1F192C0F0051B8E6 /* ReaderSiteServiceRemoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9B91F192C0F0051B8E6 /* ReaderSiteServiceRemoteTests.swift */; }; 7430C9BD1F192C0F0051B8E6 /* ReaderPostServiceRemoteTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9BA1F192C0F0051B8E6 /* ReaderPostServiceRemoteTests.m */; }; 7430C9BE1F192C0F0051B8E6 /* ReaderTopicServiceRemoteTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7430C9BB1F192C0F0051B8E6 /* ReaderTopicServiceRemoteTests.m */; }; @@ -781,6 +778,9 @@ 46ABD0E9262EEE0400C7FF24 /* AppTransportSecuritySettingsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppTransportSecuritySettingsTests.swift; sourceTree = ""; }; 4A1DEF43293051BC00322608 /* LoggingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingTests.swift; sourceTree = ""; }; 4A1DEF45293051C600322608 /* LoggingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoggingTests.m; sourceTree = ""; }; + 4A68E3DC294070A7004AC3DC /* RemoteReaderSite.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteReaderSite.swift; sourceTree = ""; }; + 4A68E3DE29407100004AC3DC /* RemoteReaderTopic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteReaderTopic.swift; sourceTree = ""; }; + 4A68E3E0294076C1004AC3DC /* RemoteReaderSiteInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteReaderSiteInfo.swift; sourceTree = ""; }; 4A68E3CC29404181004AC3DC /* RemoteBlog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteBlog.swift; sourceTree = ""; }; 4A68E3CE29404289004AC3DC /* RemoteBlogOptionsHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteBlogOptionsHelper.swift; sourceTree = ""; }; 4A68E3D029406AA0004AC3DC /* RemoteMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteMenu.swift; sourceTree = ""; }; @@ -859,12 +859,6 @@ 7430C9A21F1927180051B8E6 /* ReaderTopicServiceRemote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderTopicServiceRemote.m; sourceTree = ""; }; 7430C9A91F1927C50051B8E6 /* RemoteReaderPost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteReaderPost.h; sourceTree = ""; }; 7430C9AA1F1927C50051B8E6 /* RemoteReaderPost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteReaderPost.m; sourceTree = ""; }; - 7430C9AB1F1927C50051B8E6 /* RemoteReaderSite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteReaderSite.h; sourceTree = ""; }; - 7430C9AC1F1927C50051B8E6 /* RemoteReaderSite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteReaderSite.m; sourceTree = ""; }; - 7430C9AD1F1927C50051B8E6 /* RemoteReaderSiteInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteReaderSiteInfo.h; sourceTree = ""; }; - 7430C9AE1F1927C50051B8E6 /* RemoteReaderSiteInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteReaderSiteInfo.m; sourceTree = ""; }; - 7430C9AF1F1927C50051B8E6 /* RemoteReaderTopic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteReaderTopic.h; sourceTree = ""; }; - 7430C9B01F1927C50051B8E6 /* RemoteReaderTopic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteReaderTopic.m; sourceTree = ""; }; 7430C9B91F192C0F0051B8E6 /* ReaderSiteServiceRemoteTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReaderSiteServiceRemoteTests.swift; sourceTree = ""; }; 7430C9BA1F192C0F0051B8E6 /* ReaderPostServiceRemoteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderPostServiceRemoteTests.m; sourceTree = ""; }; 7430C9BB1F192C0F0051B8E6 /* ReaderTopicServiceRemoteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReaderTopicServiceRemoteTests.m; sourceTree = ""; }; @@ -1960,13 +1954,10 @@ 7430C9A91F1927C50051B8E6 /* RemoteReaderPost.h */, 7430C9AA1F1927C50051B8E6 /* RemoteReaderPost.m */, FACBDD1D25ECA7F90026705B /* RemoteReaderSimplePost.swift */, - 7430C9AB1F1927C50051B8E6 /* RemoteReaderSite.h */, - 7430C9AC1F1927C50051B8E6 /* RemoteReaderSite.m */, - 7430C9AD1F1927C50051B8E6 /* RemoteReaderSiteInfo.h */, - 7430C9AE1F1927C50051B8E6 /* RemoteReaderSiteInfo.m */, + 4A68E3DC294070A7004AC3DC /* RemoteReaderSite.swift */, + 4A68E3E0294076C1004AC3DC /* RemoteReaderSiteInfo.swift */, 9F3E0B9A208732B2009CB5BA /* RemoteReaderSiteInfoSubscription.swift */, - 7430C9AF1F1927C50051B8E6 /* RemoteReaderTopic.h */, - 7430C9B01F1927C50051B8E6 /* RemoteReaderTopic.m */, + 4A68E3DE29407100004AC3DC /* RemoteReaderTopic.swift */, 74E2295D1F1E777B0085F7F2 /* RemoteSharingButton.swift */, 7430C9C81F192F260051B8E6 /* RemoteSourcePostAttribution.h */, 7430C9C91F192F260051B8E6 /* RemoteSourcePostAttribution.m */, @@ -2537,10 +2528,7 @@ 74BA04F91F06DC3900ED5CD8 /* RemoteComment.h in Headers */, 74BA04F21F06DC0A00ED5CD8 /* CommentServiceRemote.h in Headers */, 74BA04F51F06DC0A00ED5CD8 /* CommentServiceRemoteXMLRPC.h in Headers */, - 7430C9B51F1927C50051B8E6 /* RemoteReaderSiteInfo.h in Headers */, 7430C9A71F1927180051B8E6 /* ReaderTopicServiceRemote.h in Headers */, - 7430C9B71F1927C50051B8E6 /* RemoteReaderTopic.h in Headers */, - 7430C9B31F1927C50051B8E6 /* RemoteReaderSite.h in Headers */, 7430C9B11F1927C50051B8E6 /* RemoteReaderPost.h in Headers */, 7430C9A51F1927180051B8E6 /* ReaderSiteServiceRemote.h in Headers */, 7430C9A31F1927180051B8E6 /* ReaderPostServiceRemote.h in Headers */, @@ -3037,7 +3025,6 @@ 32E1DD23236AA09A008914B0 /* RemotePostAutosave.swift in Sources */, FF807252241FB90E00809AF5 /* Authenticator.swift in Sources */, 464BAB0B262F6736006AEED5 /* RemoteBlockEditorSettings.swift in Sources */, - 7430C9B41F1927C50051B8E6 /* RemoteReaderSite.m in Sources */, FEFFD99126C1347D00F34231 /* ShareAppContentServiceRemote.swift in Sources */, 74585B8E1F0D51A100E7E667 /* DomainsServiceRemote.swift in Sources */, 4625B965253A343900C04AAD /* RemotePageLayouts.swift in Sources */, @@ -3075,6 +3062,7 @@ 93BD27801EE73944002BB00B /* WordPressComRestApi.swift in Sources */, 404057D2221C56AB0060250C /* StatsTopCountryTimeIntervalData.swift in Sources */, E11C2AD21FA77FB90023BDE2 /* SitePlugin.swift in Sources */, + 4A68E3DF29407100004AC3DC /* RemoteReaderTopic.swift in Sources */, 74A44DCC1F13C533006CD8F4 /* NotificationSyncServiceRemote.swift in Sources */, 8BB66DB02523C181000B29DA /* ReaderPostServiceRemote+V2.swift in Sources */, 74E229501F1E741B0085F7F2 /* RemotePublicizeConnection.swift in Sources */, @@ -3089,6 +3077,7 @@ 74650F721F0EA1A700188EDB /* GravatarServiceRemote.swift in Sources */, B5969E1D20A49AC4005E9DF1 /* NSString+MD5.m in Sources */, FF807251241FB90E00809AF5 /* WordPressOrgRestApi.swift in Sources */, + 4A68E3E1294076C1004AC3DC /* RemoteReaderSiteInfo.swift in Sources */, 8236EB4D2024B9F8007C7CF9 /* RemoteBlogJetpackModulesSettings.swift in Sources */, 73A2F38A21E7F81E00388609 /* WordPressComServiceRemote+SiteVerticalsPrompt.swift in Sources */, 740B23BB1F17EC7300067A2A /* PostServiceRemoteXMLRPC.m in Sources */, @@ -3110,14 +3099,12 @@ 93BD276A1EE736A8002BB00B /* RemoteUser.m in Sources */, 742362D71F10250600BD0A7F /* MenusServiceRemote.m in Sources */, E6D0EE621F7EF9CE0064D3FC /* AccountServiceRemoteREST+SocialService.swift in Sources */, - 7430C9B61F1927C50051B8E6 /* RemoteReaderSiteInfo.m in Sources */, 8BB5F62127A99A2000B2FFAF /* DashboardServiceRemote.swift in Sources */, 74DA56351F06EAF000FE9BF4 /* MediaServiceRemoteXMLRPC.m in Sources */, C797196C2679007B0072F984 /* PluginManagementClient.swift in Sources */, C785325625B5F46C006CEAFB /* JetpackThreatFixStatus.swift in Sources */, 93F50A381F226B9300B5BEBA /* WordPressComServiceRemote.m in Sources */, 9F4E52002088E38200424676 /* ObjectValidation.swift in Sources */, - 7430C9B81F1927C50051B8E6 /* RemoteReaderTopic.m in Sources */, 7EC60EC022DC5D7C00FB0336 /* EditorSettings.swift in Sources */, 7403A3021EF0726E00DED7DC /* AccountSettings.swift in Sources */, 40E7FEA9220FA4060032834E /* StatsEmailFollowersInsight.swift in Sources */, @@ -3169,6 +3156,7 @@ 984E34EB22EF7209005C3F92 /* StatsFileDownloadsTimeIntervalData.swift in Sources */, 465F88A2263B325C00F4C950 /* ChecksumUtil.swift in Sources */, C7A09A52284104DB003096ED /* QRLoginServiceRemote.swift in Sources */, + 4A68E3DD294070A7004AC3DC /* RemoteReaderSite.swift in Sources */, 40AB1ADA200FED25009B533D /* PluginDirectoryFeedPage.swift in Sources */, 436D56352118D85800CEAA33 /* WPCountry.swift in Sources */, 74A44DCB1F13C533006CD8F4 /* NotificationSettingsServiceRemote.swift in Sources */, diff --git a/WordPressKit/ReaderSiteServiceRemote.m b/WordPressKit/ReaderSiteServiceRemote.m index 0e5d14d3..60609725 100644 --- a/WordPressKit/ReaderSiteServiceRemote.m +++ b/WordPressKit/ReaderSiteServiceRemote.m @@ -1,5 +1,4 @@ #import "ReaderSiteServiceRemote.h" -#import "RemoteReaderSite.h" #import "WPKit-Swift.h" @import NSObject_SafeExpectations; @import WordPressShared; diff --git a/WordPressKit/ReaderTopicServiceRemote.m b/WordPressKit/ReaderTopicServiceRemote.m index ad2df264..715dbbd0 100644 --- a/WordPressKit/ReaderTopicServiceRemote.m +++ b/WordPressKit/ReaderTopicServiceRemote.m @@ -1,6 +1,4 @@ #import "ReaderTopicServiceRemote.h" -#import "RemoteReaderTopic.h" -#import "RemoteReaderSiteInfo.h" #import "WPKit-Swift.h" @import NSObject_SafeExpectations; @import WordPressShared; diff --git a/WordPressKit/RemoteReaderCard.swift b/WordPressKit/RemoteReaderCard.swift index edfef4e4..f37376ef 100644 --- a/WordPressKit/RemoteReaderCard.swift +++ b/WordPressKit/RemoteReaderCard.swift @@ -43,13 +43,11 @@ public struct RemoteReaderCard: Decodable { let sitesArray = try container.decode([Any].self, forKey: .data) sites = sitesArray.compactMap { - // Since RemoteReaderSiteInfo is written in Obj-C and doesn't support decoding - // attempt to recast the response as a dictionary value to be passed to the init below - guard let dict = $0 as? [AnyHashable: Any] else { + guard let dict = $0 as? NSDictionary else { return nil } - return RemoteReaderSiteInfo(forSiteResponse: dict, isFeed: false) + return RemoteReaderSiteInfo.siteInfo(forSiteResponse: dict, isFeed: false) } default: diff --git a/WordPressKit/RemoteReaderSite.h b/WordPressKit/RemoteReaderSite.h deleted file mode 100644 index 3fb878d7..00000000 --- a/WordPressKit/RemoteReaderSite.h +++ /dev/null @@ -1,13 +0,0 @@ -#import - -@interface RemoteReaderSite : NSObject - -@property (nonatomic, strong) NSNumber *recordID; -@property (nonatomic, strong) NSNumber *siteID; -@property (nonatomic, strong) NSNumber *feedID; -@property (nonatomic, strong) NSString *name; -@property (nonatomic, strong) NSString *path; // URL -@property (nonatomic, strong) NSString *icon; // Sites only -@property (nonatomic) BOOL isSubscribed; - -@end diff --git a/WordPressKit/RemoteReaderSite.m b/WordPressKit/RemoteReaderSite.m deleted file mode 100644 index c81b40cb..00000000 --- a/WordPressKit/RemoteReaderSite.m +++ /dev/null @@ -1,5 +0,0 @@ -#import "RemoteReaderSite.h" - -@implementation RemoteReaderSite - -@end diff --git a/WordPressKit/RemoteReaderSite.swift b/WordPressKit/RemoteReaderSite.swift new file mode 100644 index 00000000..5b3f35dc --- /dev/null +++ b/WordPressKit/RemoteReaderSite.swift @@ -0,0 +1,13 @@ +import Foundation + +@objcMembers public class RemoteReaderSite: NSObject { + + public var recordID: NSNumber? + public var siteID: NSNumber? + public var feedID: NSNumber? + public var name: String? + public var path: String? // URL + public var icon: String? // Sites only + public var isSubscribed: Bool = false + +} diff --git a/WordPressKit/RemoteReaderSiteInfo.h b/WordPressKit/RemoteReaderSiteInfo.h deleted file mode 100644 index 3f8b1512..00000000 --- a/WordPressKit/RemoteReaderSiteInfo.h +++ /dev/null @@ -1,31 +0,0 @@ -#import - - -@class RemoteReaderSiteInfoSubscriptionEmail; -@class RemoteReaderSiteInfoSubscriptionPost; - - -@interface RemoteReaderSiteInfo: NSObject -@property (nonatomic, copy) NSNumber *feedID; -@property (nonatomic, copy) NSString *feedURL; -@property (nonatomic) BOOL isFollowing; -@property (nonatomic) BOOL isJetpack; -@property (nonatomic) BOOL isPrivate; -@property (nonatomic) BOOL isVisible; -@property (nonatomic, copy) NSNumber *organizationID; -@property (nonatomic, copy) NSNumber *postCount; -@property (nonatomic, copy) NSString *siteBlavatar; -@property (nonatomic, copy) NSString *siteDescription; -@property (nonatomic, copy) NSNumber *siteID; -@property (nonatomic, copy) NSString *siteName; -@property (nonatomic, copy) NSString *siteURL; -@property (nonatomic, copy) NSNumber *subscriberCount; -@property (nonatomic, copy) NSNumber *unseenCount; -@property (nonatomic, copy) NSString *postsEndpoint; -@property (nonatomic, copy) NSString *endpointPath; - -@property (nonatomic, strong) RemoteReaderSiteInfoSubscriptionPost *postSubscription; -@property (nonatomic, strong) RemoteReaderSiteInfoSubscriptionEmail *emailSubscription; - -+ (instancetype)siteInfoForSiteResponse:(NSDictionary *)response isFeed:(BOOL)isFeed; -@end diff --git a/WordPressKit/RemoteReaderSiteInfo.m b/WordPressKit/RemoteReaderSiteInfo.m deleted file mode 100644 index fc29600b..00000000 --- a/WordPressKit/RemoteReaderSiteInfo.m +++ /dev/null @@ -1,137 +0,0 @@ -#import "RemoteReaderSiteInfo.h" -#import "WPKit-Swift.h" - -@import NSObject_SafeExpectations; - -// Site Topic Keys -static NSString * const SiteDictionaryFeedIDKey = @"feed_ID"; -static NSString * const SiteDictionaryFeedURLKey = @"feed_URL"; -static NSString * const SiteDictionaryFollowingKey = @"is_following"; -static NSString * const SiteDictionaryJetpackKey = @"is_jetpack"; -static NSString * const SiteDictionaryOrganizationID = @"organization_id"; -static NSString * const SiteDictionaryPrivateKey = @"is_private"; -static NSString * const SiteDictionaryVisibleKey = @"visible"; -static NSString * const SiteDictionaryPostCountKey = @"post_count"; -static NSString * const SiteDictionaryIconPathKey = @"icon.img"; -static NSString * const SiteDictionaryDescriptionKey = @"description"; -static NSString * const SiteDictionaryIDKey = @"ID"; -static NSString * const SiteDictionaryNameKey = @"name"; -static NSString * const SiteDictionaryURLKey = @"URL"; -static NSString * const SiteDictionarySubscriptionsKey = @"subscribers_count"; -static NSString * const SiteDictionarySubscriptionKey = @"subscription"; -static NSString * const SiteDictionaryUnseenCountKey = @"unseen_count"; - -// Subscription keys -static NSString * const SubscriptionDeliveryMethodsKey = @"delivery_methods"; - -// Delivery methods keys -static NSString * const DeliveryMethodEmailKey = @"email"; -static NSString * const DeliveryMethodNotificationKey = @"notification"; - -@implementation RemoteReaderSiteInfo - -+ (instancetype)siteInfoForSiteResponse:(NSDictionary *)response isFeed:(BOOL)isFeed -{ - if (isFeed) { - return [self siteInfoForFeedResponse:response]; - } - - RemoteReaderSiteInfo *siteInfo = [RemoteReaderSiteInfo new]; - siteInfo.feedID = [response numberForKey:SiteDictionaryFeedIDKey]; - siteInfo.feedURL = [response stringForKey:SiteDictionaryFeedURLKey]; - siteInfo.isFollowing = [[response numberForKey:SiteDictionaryFollowingKey] boolValue]; - siteInfo.isJetpack = [[response numberForKey:SiteDictionaryJetpackKey] boolValue]; - siteInfo.isPrivate = [[response numberForKey:SiteDictionaryPrivateKey] boolValue]; - siteInfo.isVisible = [[response numberForKey:SiteDictionaryVisibleKey] boolValue]; - siteInfo.organizationID = [response numberForKey:SiteDictionaryOrganizationID] ?: @0; - siteInfo.postCount = [response numberForKey:SiteDictionaryPostCountKey]; - siteInfo.siteBlavatar = [response stringForKeyPath:SiteDictionaryIconPathKey]; - siteInfo.siteDescription = [response stringForKey:SiteDictionaryDescriptionKey]; - siteInfo.siteID = [response numberForKey:SiteDictionaryIDKey]; - siteInfo.siteName = [response stringForKey:SiteDictionaryNameKey]; - siteInfo.siteURL = [response stringForKey:SiteDictionaryURLKey]; - siteInfo.subscriberCount = [response numberForKey:SiteDictionarySubscriptionsKey] ?: @0; - siteInfo.unseenCount = [response numberForKey: SiteDictionaryUnseenCountKey] ?: @0; - - if (![siteInfo.siteName length] && [siteInfo.siteURL length] > 0) { - siteInfo.siteName = [[NSURL URLWithString:siteInfo.siteURL] host]; - } - - siteInfo.endpointPath = [NSString stringWithFormat:@"read/sites/%@/posts/", siteInfo.siteID]; - - NSDictionary *subscription = response[SiteDictionarySubscriptionKey]; - siteInfo.postSubscription = [self.class postSubscriptionFor:subscription]; - siteInfo.emailSubscription = [self.class emailSubscriptionFor:subscription]; - - return siteInfo; -} - -+ (instancetype)siteInfoForFeedResponse:(NSDictionary *)response -{ - RemoteReaderSiteInfo *siteInfo = [RemoteReaderSiteInfo new]; - siteInfo.feedID = [response numberForKey:SiteDictionaryFeedIDKey]; - siteInfo.feedURL = [response stringForKey:SiteDictionaryFeedURLKey]; - siteInfo.isFollowing = [[response numberForKey:SiteDictionaryFollowingKey] boolValue]; - siteInfo.isJetpack = NO; - siteInfo.isPrivate = NO; - siteInfo.isVisible = YES; - siteInfo.postCount = @0; - siteInfo.siteBlavatar = @""; - siteInfo.siteDescription = @""; - siteInfo.siteID = @0; - siteInfo.siteName = [response stringForKey:SiteDictionaryNameKey]; - siteInfo.siteURL = [response stringForKey:SiteDictionaryURLKey]; - siteInfo.subscriberCount = [response numberForKey:SiteDictionarySubscriptionsKey] ?: @0; - - if (![siteInfo.siteName length] && [siteInfo.siteURL length] > 0) { - siteInfo.siteName = [[NSURL URLWithString:siteInfo.siteURL] host]; - } - - siteInfo.endpointPath = [NSString stringWithFormat:@"read/feed/%@/posts/", siteInfo.feedID]; - - return siteInfo; -} - -/** - Generate an Site Info Post Subscription object - - @param subscription A dictionary object for the site subscription - @return A nullable Site Info Post Subscription - */ -+ (RemoteReaderSiteInfoSubscriptionPost *)postSubscriptionFor:(NSDictionary *)subscription -{ - if (![subscription wp_isValidObject]) { - return nil; - } - - NSDictionary *method = [[subscription dictionaryForKey: SubscriptionDeliveryMethodsKey] dictionaryForKey: DeliveryMethodNotificationKey]; - - if (![method wp_isValidObject]) { - return nil; - } - - return [[RemoteReaderSiteInfoSubscriptionPost alloc] initWithDictionary:method]; -} - -/** - Generate an Site Info Email Subscription object - - @param subscription A dictionary object for the site subscription - @return A nullable Site Info Email Subscription - */ - -+ (RemoteReaderSiteInfoSubscriptionEmail *)emailSubscriptionFor:(NSDictionary *)subscription -{ - if (![subscription wp_isValidObject]) { - return nil; - } - - NSDictionary *method = [[subscription dictionaryForKey: SubscriptionDeliveryMethodsKey] dictionaryForKey: DeliveryMethodEmailKey]; - - if (![method wp_isValidObject]) { - return nil; - } - - return [[RemoteReaderSiteInfoSubscriptionEmail alloc] initWithDictionary:method]; -} -@end diff --git a/WordPressKit/RemoteReaderSiteInfo.swift b/WordPressKit/RemoteReaderSiteInfo.swift new file mode 100644 index 00000000..cde80240 --- /dev/null +++ b/WordPressKit/RemoteReaderSiteInfo.swift @@ -0,0 +1,154 @@ +import Foundation +import NSObject_SafeExpectations + +// Site Topic Keys +private let SiteDictionaryFeedIDKey = "feed_ID" +private let SiteDictionaryFeedURLKey = "feed_URL" +private let SiteDictionaryFollowingKey = "is_following" +private let SiteDictionaryJetpackKey = "is_jetpack" +private let SiteDictionaryOrganizationID = "organization_id" +private let SiteDictionaryPrivateKey = "is_private" +private let SiteDictionaryVisibleKey = "visible" +private let SiteDictionaryPostCountKey = "post_count" +private let SiteDictionaryIconPathKey = "icon.img" +private let SiteDictionaryDescriptionKey = "description" +private let SiteDictionaryIDKey = "ID" +private let SiteDictionaryNameKey = "name" +private let SiteDictionaryURLKey = "URL" +private let SiteDictionarySubscriptionsKey = "subscribers_count" +private let SiteDictionarySubscriptionKey = "subscription" +private let SiteDictionaryUnseenCountKey = "unseen_count" + +// Subscription keys +private let SubscriptionDeliveryMethodsKey = "delivery_methods" + +// Delivery methods keys +private let DeliveryMethodEmailKey = "email" +private let DeliveryMethodNotificationKey = "notification" + +@objcMembers public class RemoteReaderSiteInfo: NSObject { + public var feedID: NSNumber? + public var feedURL: String? + public var isFollowing: Bool = false + public var isJetpack: Bool = false + public var isPrivate: Bool = false + public var isVisible: Bool = false + public var organizationID: NSNumber? + public var postCount: NSNumber? + public var siteBlavatar: String? + public var siteDescription: String? + public var siteID: NSNumber? + public var siteName: String? + public var siteURL: String? + public var subscriberCount: NSNumber? + public var unseenCount: NSNumber? + public var postsEndpoint: String? + public var endpointPath: String? + + public var postSubscription: RemoteReaderSiteInfoSubscriptionPost? + public var emailSubscription: RemoteReaderSiteInfoSubscriptionEmail? + + public class func siteInfo(forSiteResponse response: NSDictionary, isFeed: Bool) -> RemoteReaderSiteInfo { + if isFeed { + return siteInfo(forFeedResponse: response) + } + + let siteInfo = RemoteReaderSiteInfo() + siteInfo.feedID = response.number(forKey: SiteDictionaryFeedIDKey) + siteInfo.feedURL = response.string(forKey: SiteDictionaryFeedURLKey) + siteInfo.isFollowing = response.number(forKey: SiteDictionaryFollowingKey)?.boolValue ?? false + siteInfo.isJetpack = response.number(forKey: SiteDictionaryJetpackKey)?.boolValue ?? false + siteInfo.isPrivate = response.number(forKey: SiteDictionaryPrivateKey)?.boolValue ?? false + siteInfo.isVisible = response.number(forKey: SiteDictionaryVisibleKey)?.boolValue ?? false + siteInfo.organizationID = response.number(forKey: SiteDictionaryOrganizationID) ?? 0 + siteInfo.postCount = response.number(forKey: SiteDictionaryPostCountKey) + siteInfo.siteBlavatar = response.string(forKeyPath: SiteDictionaryIconPathKey) + siteInfo.siteDescription = response.string(forKey: SiteDictionaryDescriptionKey) + siteInfo.siteID = response.number(forKey: SiteDictionaryIDKey) + siteInfo.siteName = response.string(forKey: SiteDictionaryNameKey) + siteInfo.siteURL = response.string(forKey: SiteDictionaryURLKey) + siteInfo.subscriberCount = response.number(forKey: SiteDictionarySubscriptionsKey) ?? 0 + siteInfo.unseenCount = response.number(forKey: SiteDictionaryUnseenCountKey) ?? 0 + + if (siteInfo.siteName?.count ?? 0) == 0, + let siteURLString = siteInfo.siteURL, + let siteURL = URL(string: siteURLString) { + siteInfo.siteName = siteURL.host + } + + siteInfo.endpointPath = "read/sites/\(siteInfo.siteID ?? 0)/posts/" + + if let subscription = response[SiteDictionarySubscriptionKey] as? NSDictionary { + siteInfo.postSubscription = postSubscription(forSubscription: subscription) + siteInfo.emailSubscription = emailSubscription(forSubscription: subscription) + } + + return siteInfo + } + +} + +private extension RemoteReaderSiteInfo { + class func siteInfo(forFeedResponse response: NSDictionary) -> RemoteReaderSiteInfo { + let siteInfo = RemoteReaderSiteInfo() + siteInfo.feedID = response.number(forKey: SiteDictionaryFeedIDKey) + siteInfo.feedURL = response.string(forKey: SiteDictionaryFeedURLKey) + siteInfo.isFollowing = response.number(forKey: SiteDictionaryFollowingKey)?.boolValue ?? false + siteInfo.isJetpack = false + siteInfo.isPrivate = false + siteInfo.isVisible = true + siteInfo.postCount = 0 + siteInfo.siteBlavatar = "" + siteInfo.siteDescription = "" + siteInfo.siteID = 0 + siteInfo.siteName = response.string(forKey: SiteDictionaryNameKey) + siteInfo.siteURL = response.string(forKey: SiteDictionaryURLKey) + siteInfo.subscriberCount = response.number(forKey: SiteDictionarySubscriptionsKey) ?? 0 + + if (siteInfo.siteName?.count ?? 0) == 0, + let siteURLString = siteInfo.siteURL, + let siteURL = URL(string: siteURLString) { + siteInfo.siteName = siteURL.host + } + + siteInfo.endpointPath = "read/feed/\(siteInfo.feedID ?? 0)/posts/" + + return siteInfo + } + + /// Generate an Site Info Post Subscription object + /// + /// - Parameter subscription A dictionary object for the site subscription + /// - Returns A nullable Site Info Post Subscription + class func postSubscription(forSubscription subscription: NSDictionary) -> RemoteReaderSiteInfoSubscriptionPost? { + guard subscription.wp_isValidObject() else { + return nil + } + + guard let deliveryMethod = subscription[SubscriptionDeliveryMethodsKey] as? [String: Any], + let method = deliveryMethod[DeliveryMethodNotificationKey] as? [String: Any] + else { + return nil + } + + return RemoteReaderSiteInfoSubscriptionPost(dictionary: method) + } + + /// Generate an Site Info Email Subscription object + /// + /// - Parameter subscription A dictionary object for the site subscription + /// - Returns A nullable Site Info Email Subscription + class func emailSubscription(forSubscription subscription: NSDictionary) -> RemoteReaderSiteInfoSubscriptionEmail? { + guard subscription.wp_isValidObject() else { + return nil + } + + guard let delieveryMethod = subscription[SubscriptionDeliveryMethodsKey] as? [String: Any], + let method = delieveryMethod[DeliveryMethodEmailKey] as? [String: Any] + else { + return nil + } + + return RemoteReaderSiteInfoSubscriptionEmail(dictionary: method) + } +} diff --git a/WordPressKit/RemoteReaderTopic.h b/WordPressKit/RemoteReaderTopic.h deleted file mode 100644 index f7b543ac..00000000 --- a/WordPressKit/RemoteReaderTopic.h +++ /dev/null @@ -1,17 +0,0 @@ -#import - -@interface RemoteReaderTopic : NSObject - -@property (nonatomic) BOOL isMenuItem; -@property (nonatomic) BOOL isRecommended; -@property (nonatomic) BOOL isSubscribed; -@property (nonatomic, strong) NSString *path; -@property (nonatomic, strong) NSString *slug; -@property (nonatomic, strong) NSString *title; -@property (nonatomic, strong) NSString *topicDescription; -@property (nonatomic, strong) NSNumber *topicID; -@property (nonatomic, strong) NSString *type; -@property (nonatomic, strong) NSString *owner; -@property (nonatomic, strong) NSNumber *organizationID; - -@end diff --git a/WordPressKit/RemoteReaderTopic.m b/WordPressKit/RemoteReaderTopic.m deleted file mode 100644 index bbda695a..00000000 --- a/WordPressKit/RemoteReaderTopic.m +++ /dev/null @@ -1,5 +0,0 @@ -#import "RemoteReaderTopic.h" - -@implementation RemoteReaderTopic - -@end diff --git a/WordPressKit/RemoteReaderTopic.swift b/WordPressKit/RemoteReaderTopic.swift new file mode 100644 index 00000000..71578323 --- /dev/null +++ b/WordPressKit/RemoteReaderTopic.swift @@ -0,0 +1,17 @@ +import Foundation + +@objcMembers public class RemoteReaderTopic: NSObject { + + public var isMenuItem: Bool = false + public var isRecommended: Bool = false + public var isSubscribed: Bool = false + public var path: String? + public var slug: String? + public var title: String? + public var topicDescription: String? + public var topicID: NSNumber? + public var type: String? + public var owner: String? + public var organizationID: NSNumber? + +} diff --git a/WordPressKit/WordPressKit.h b/WordPressKit/WordPressKit.h index 8a106a0f..2fe628dd 100644 --- a/WordPressKit/WordPressKit.h +++ b/WordPressKit/WordPressKit.h @@ -42,9 +42,6 @@ FOUNDATION_EXPORT const unsigned char WordPressKitVersionString[]; #import #import #import -#import -#import -#import #import #import #import diff --git a/WordPressKitTests/ReaderPostServiceRemoteTests.m b/WordPressKitTests/ReaderPostServiceRemoteTests.m index 4ce42ee3..e48c7371 100644 --- a/WordPressKitTests/ReaderPostServiceRemoteTests.m +++ b/WordPressKitTests/ReaderPostServiceRemoteTests.m @@ -1,6 +1,5 @@ #import #import "ReaderTopicServiceRemote.h" -#import "RemoteReaderTopic.h" #import "ReaderPostServiceRemote.h" #import "RemoteReaderPost.h" #import "WPKit-Swift.h" diff --git a/WordPressKitTests/ReaderTopicServiceRemoteTests.m b/WordPressKitTests/ReaderTopicServiceRemoteTests.m index b68beaf6..83581109 100644 --- a/WordPressKitTests/ReaderTopicServiceRemoteTests.m +++ b/WordPressKitTests/ReaderTopicServiceRemoteTests.m @@ -1,7 +1,6 @@ #import #import "ReaderTopicServiceRemote.h" -#import "RemoteReaderTopic.h" #import "WPKit-Swift.h" @interface ReaderTopicServiceRemote() diff --git a/WordPressKitTests/RemoteReaderPostTests.m b/WordPressKitTests/RemoteReaderPostTests.m index 0306435d..50a3c751 100644 --- a/WordPressKitTests/RemoteReaderPostTests.m +++ b/WordPressKitTests/RemoteReaderPostTests.m @@ -1,7 +1,6 @@ #import #import "ReaderTopicServiceRemote.h" -#import "RemoteReaderTopic.h" #import "ReaderPostServiceRemote.h" #import "RemoteReaderPost.h" #import "WPKit-Swift.h"