From 5c95ca15706cf497b05bc00ae6b635f2839c4e9c Mon Sep 17 00:00:00 2001 From: John Kuan Date: Mon, 5 Nov 2018 20:51:23 +0800 Subject: [PATCH 1/5] Updated deprecated flatMap to compactMap --- Vox/Core/Class/Context.swift | 4 ++-- Vox/Core/Class/Context_Query.swift | 2 +- Vox/Core/Networking/Protocol/FetchPageable.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Vox/Core/Class/Context.swift b/Vox/Core/Class/Context.swift index 621f2ad..97a2e3e 100644 --- a/Vox/Core/Class/Context.swift +++ b/Vox/Core/Class/Context.swift @@ -31,7 +31,7 @@ public class Context: NSObject { let resource = mapResource(for: data) dataType = .resource(resource) } else if let data = dictionary["data"] as? NSMutableArray { - let resources = data.flatMap({ (resourceData) -> Resource? in + let resources = data.compactMap({ (resourceData) -> Resource? in guard let dictionary = resourceData as? NSMutableDictionary else { fatalError("Invalid data type") } let resource = mapResource(for: dictionary) @@ -40,7 +40,7 @@ public class Context: NSObject { dataType = .collection(resources) } else if let errors = dictionary["errors"] as? NSMutableArray { - let errorObjects = errors.flatMap({ (object) -> ErrorObject? in + let errorObjects = errors.compactMap({ (object) -> ErrorObject? in guard let object = object as? [String: Any] else { return nil } return ErrorObject(dictionary: object) }) diff --git a/Vox/Core/Class/Context_Query.swift b/Vox/Core/Class/Context_Query.swift index 95a173a..5eda171 100644 --- a/Vox/Core/Class/Context_Query.swift +++ b/Vox/Core/Class/Context_Query.swift @@ -17,7 +17,7 @@ extension Context { let data = relationshipDocumentData["data"] if let arrayOfBasicObjects = data as? NSMutableArray { - value = arrayOfBasicObjects.flatMap({ (basicObject) -> Resource? in + value = arrayOfBasicObjects.compactMap({ (basicObject) -> Resource? in return resourcePool.resource(forBasicObject: basicObject as! [String: String]) }) } else if let basicObject = data as? NSMutableDictionary { diff --git a/Vox/Core/Networking/Protocol/FetchPageable.swift b/Vox/Core/Networking/Protocol/FetchPageable.swift index 3b52376..1ebe575 100644 --- a/Vox/Core/Networking/Protocol/FetchPageable.swift +++ b/Vox/Core/Networking/Protocol/FetchPageable.swift @@ -106,7 +106,7 @@ public extension Document where DataType: Collection, DataType.Element: Resource if let array = document.context.dictionary["data"] as? [Any] { let selfData = self.context.dictionary["data"] as? NSMutableArray - let resources = array.flatMap({ (resourceJson) -> Resource? in + let resources = array.compactMap({ (resourceJson) -> Resource? in guard let resourceJson = resourceJson as? NSMutableDictionary else { return nil } let copy = resourceJson.mutableCopy() as! NSMutableDictionary From 9bddb2ccf0c81a31930d99dc141bb8bb64e83a6f Mon Sep 17 00:00:00 2001 From: John Kuan Date: Tue, 6 Nov 2018 00:46:15 +0800 Subject: [PATCH 2/5] Added support to parse links to Dictionary in Resource --- Vox/Core/Class/Context_Query.swift | 7 ++++++ Vox/Core/Class/Resource.swift | 22 +++++++++++++++++++ VoxTests/Assets/Articles.json | 12 +++++++++- .../DeserializerCollectionSpec.swift | 5 +++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Vox/Core/Class/Context_Query.swift b/Vox/Core/Class/Context_Query.swift index 5eda171..1be817d 100644 --- a/Vox/Core/Class/Context_Query.swift +++ b/Vox/Core/Class/Context_Query.swift @@ -25,6 +25,13 @@ extension Context { } else if data is NSNull { value = nil } + } else if let linkDocumentData = resource.object?.value(forKeyPath: "links.\(key)") { + if let stringObject = linkDocumentData as? String, let urlObject = URL(string: stringObject) { + value = urlObject // assume simple string url + } else if let dictionary = linkDocumentData as? [String: Any] { + // need to parse { href: "", meta : {..}} + value = dictionary + } } } diff --git a/Vox/Core/Class/Resource.swift b/Vox/Core/Class/Resource.swift index c885a0a..83f66f7 100644 --- a/Vox/Core/Class/Resource.swift +++ b/Vox/Core/Class/Resource.swift @@ -48,6 +48,16 @@ open class Resource: BaseResource { return _relationships } + + public var links: NSMutableDictionary? { + var _links: NSMutableDictionary? + + context?.queue.sync { + _links = object?["links"] as? NSMutableDictionary + } + + return _links + } public required init(context: Context? = nil) { super.init() @@ -77,6 +87,7 @@ open class Resource: BaseResource { public func documentDictionary() throws -> [String: Any] { let attributes = self.attributes let relationships = self.relationships + let links = self.links var dictionary: [String: Any] = [ "type": self.type @@ -95,6 +106,11 @@ open class Resource: BaseResource { relationships.count > 0 { dictionary["relationships"] = relationships } + + if let links = links, + links.count > 0 { + dictionary["links"] = links + } return ["data": dictionary] } @@ -131,6 +147,7 @@ extension Array where Element: Resource { let attributes = resource.attributes let relationships = resource.relationships + let links = resource.links var dictionary: [String: Any] = [ "id": id, @@ -146,6 +163,11 @@ extension Array where Element: Resource { relationships.count > 0 { dictionary["relationships"] = relationships } + + if let links = links, + links.count > 0 { + dictionary["links"] = links + } return dictionary } diff --git a/VoxTests/Assets/Articles.json b/VoxTests/Assets/Articles.json index 9d33b90..276bf62 100644 --- a/VoxTests/Assets/Articles.json +++ b/VoxTests/Assets/Articles.json @@ -37,7 +37,17 @@ "type": "persons2" } } - } + }, + "links": { + "here": "www.example.com", + "there": "www.example2.com", + "related": { + "href": "http://example.com/articles/1/comments", + "meta": { + "count": 10 + } + } + } }], "included": [ { diff --git a/VoxTests/Deserializer/DeserializerCollectionSpec.swift b/VoxTests/Deserializer/DeserializerCollectionSpec.swift index 0f3e771..d21b657 100644 --- a/VoxTests/Deserializer/DeserializerCollectionSpec.swift +++ b/VoxTests/Deserializer/DeserializerCollectionSpec.swift @@ -23,6 +23,9 @@ fileprivate class Article2: Resource { @objc dynamic var author: Person2? @objc dynamic var hint: String? @objc dynamic var customObject: [String: Any]? + @objc dynamic var here: URL? + @objc dynamic var there: URL? + @objc dynamic var related: [String: Any]? } @@ -61,6 +64,8 @@ class DeserializerCollectionSpec: QuickSpec { expect(article?.descriptionText).to(equal("Desc")) expect(article?.keywords).notTo(beNil()) expect(article?.customObject).notTo(beNil()) + expect(article?.here).to(equal(URL(string: "www.example.com")!)) + expect(article?.related).notTo(beNil()) let coauthors = article?.coauthors let author = article?.author From bf86135da61352b0671f397e361cc8a64267476a Mon Sep 17 00:00:00 2001 From: John Kuan Date: Tue, 6 Nov 2018 00:48:50 +0800 Subject: [PATCH 3/5] added test for article.links --- VoxTests/Deserializer/DeserializerCollectionSpec.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VoxTests/Deserializer/DeserializerCollectionSpec.swift b/VoxTests/Deserializer/DeserializerCollectionSpec.swift index d21b657..07b3031 100644 --- a/VoxTests/Deserializer/DeserializerCollectionSpec.swift +++ b/VoxTests/Deserializer/DeserializerCollectionSpec.swift @@ -66,7 +66,7 @@ class DeserializerCollectionSpec: QuickSpec { expect(article?.customObject).notTo(beNil()) expect(article?.here).to(equal(URL(string: "www.example.com")!)) expect(article?.related).notTo(beNil()) - + expect(article?.links).notTo(beNil()) let coauthors = article?.coauthors let author = article?.author From e84cf69a41c66a5881be974b88ce903644a37e15 Mon Sep 17 00:00:00 2001 From: John Kuan Date: Tue, 6 Nov 2018 00:53:07 +0800 Subject: [PATCH 4/5] add test case for article?.links --- VoxTests/Deserializer/DeserializerCollectionSpec.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VoxTests/Deserializer/DeserializerCollectionSpec.swift b/VoxTests/Deserializer/DeserializerCollectionSpec.swift index d21b657..07b3031 100644 --- a/VoxTests/Deserializer/DeserializerCollectionSpec.swift +++ b/VoxTests/Deserializer/DeserializerCollectionSpec.swift @@ -66,7 +66,7 @@ class DeserializerCollectionSpec: QuickSpec { expect(article?.customObject).notTo(beNil()) expect(article?.here).to(equal(URL(string: "www.example.com")!)) expect(article?.related).notTo(beNil()) - + expect(article?.links).notTo(beNil()) let coauthors = article?.coauthors let author = article?.author From 6159956e1a7d75bbf308a370180b3eccbd172373 Mon Sep 17 00:00:00 2001 From: John Kuan Date: Wed, 7 Nov 2018 09:49:51 +0800 Subject: [PATCH 5/5] Revert "Updated deprecated flatMap to compactMap" This reverts commit 5c95ca15706cf497b05bc00ae6b635f2839c4e9c. --- Vox/Core/Class/Context.swift | 4 ++-- Vox/Core/Class/Context_Query.swift | 2 +- Vox/Core/Networking/Protocol/FetchPageable.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Vox/Core/Class/Context.swift b/Vox/Core/Class/Context.swift index 97a2e3e..621f2ad 100644 --- a/Vox/Core/Class/Context.swift +++ b/Vox/Core/Class/Context.swift @@ -31,7 +31,7 @@ public class Context: NSObject { let resource = mapResource(for: data) dataType = .resource(resource) } else if let data = dictionary["data"] as? NSMutableArray { - let resources = data.compactMap({ (resourceData) -> Resource? in + let resources = data.flatMap({ (resourceData) -> Resource? in guard let dictionary = resourceData as? NSMutableDictionary else { fatalError("Invalid data type") } let resource = mapResource(for: dictionary) @@ -40,7 +40,7 @@ public class Context: NSObject { dataType = .collection(resources) } else if let errors = dictionary["errors"] as? NSMutableArray { - let errorObjects = errors.compactMap({ (object) -> ErrorObject? in + let errorObjects = errors.flatMap({ (object) -> ErrorObject? in guard let object = object as? [String: Any] else { return nil } return ErrorObject(dictionary: object) }) diff --git a/Vox/Core/Class/Context_Query.swift b/Vox/Core/Class/Context_Query.swift index 1be817d..86dc5d8 100644 --- a/Vox/Core/Class/Context_Query.swift +++ b/Vox/Core/Class/Context_Query.swift @@ -17,7 +17,7 @@ extension Context { let data = relationshipDocumentData["data"] if let arrayOfBasicObjects = data as? NSMutableArray { - value = arrayOfBasicObjects.compactMap({ (basicObject) -> Resource? in + value = arrayOfBasicObjects.flatMap({ (basicObject) -> Resource? in return resourcePool.resource(forBasicObject: basicObject as! [String: String]) }) } else if let basicObject = data as? NSMutableDictionary { diff --git a/Vox/Core/Networking/Protocol/FetchPageable.swift b/Vox/Core/Networking/Protocol/FetchPageable.swift index 1ebe575..3b52376 100644 --- a/Vox/Core/Networking/Protocol/FetchPageable.swift +++ b/Vox/Core/Networking/Protocol/FetchPageable.swift @@ -106,7 +106,7 @@ public extension Document where DataType: Collection, DataType.Element: Resource if let array = document.context.dictionary["data"] as? [Any] { let selfData = self.context.dictionary["data"] as? NSMutableArray - let resources = array.compactMap({ (resourceJson) -> Resource? in + let resources = array.flatMap({ (resourceJson) -> Resource? in guard let resourceJson = resourceJson as? NSMutableDictionary else { return nil } let copy = resourceJson.mutableCopy() as! NSMutableDictionary