Skip to content

Commit

Permalink
Fixing realm object toJsonString issue
Browse files Browse the repository at this point in the history
See #227
  • Loading branch information
Vermeer, Edwin authored and Vermeer, Edwin committed Oct 5, 2017
1 parent e2f454a commit 31e31df
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 65 deletions.
68 changes: 35 additions & 33 deletions Demo/Demo/MoyaRxViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,53 @@ class ViewController: BaseViewController {
// MARK: - API Stuff

override func downloadRepositories(_ username: String) {
GitHubRxMoyaProvider.request(.userRepositories(username))
.map(toArray: Repository.self)
.subscribe { event -> Void in
switch event {
case .next(let repos):
self.repos = repos
GitHubRxMoyaProvider.request(.userRepositories(username)) { (result) in
switch result {
case .success(let response):
do {
self.repos = try response.RmapArray(to: Repository.self)
self.tableView.reloadData()
case .error(let error):
print(error)
let alertController = UIAlertController(title: "GitHub Fetch", message: error.localizedDescription, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
alertController.dismiss(animated: true, completion: nil)
})
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
default:
break
} catch let error {
print("parse error = \(error)")
self.showError(error)
}
}.addDisposableTo(disposeBag)
case .failure(let error):
print("request error = \(error)")
self.showError(error)
}
}
}

override func downloadZen() {
GitHubRxMoyaProvider.request(.zen)
.subscribe { event -> Void in
switch event {
case .next(let result):
let message = (try? result.mapString()) ?? "Couldn't access API"
GitHubRxMoyaProvider.request(.zen) { (result) in
switch result {
case .success(let response):
do {
let message = try response.mapString()
let alertController = UIAlertController(title: "Zen", message: message, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
alertController.dismiss(animated: true, completion: nil)
})
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
case .error(let error):
print(error)
let alertController = UIAlertController(title: "GitHub Fetch", message: error.localizedDescription, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
alertController.dismiss(animated: true, completion: nil)
})
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
default:
break
} catch let error {
print("parse error = \(error)")
self.showError(error)
}
}.addDisposableTo(disposeBag)
case .failure(let error):
print("request error = \(error)")
self.showError(error)
}
}
}

func showError(_ error: Error) {
let alertController = UIAlertController(title: "GitHub Fetch", message: error.localizedDescription, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
alertController.dismiss(animated: true, completion: nil)
})
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
}
}

7 changes: 2 additions & 5 deletions Demo/Demo/MoyaViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class MoyaViewController: BaseViewController {
switch result {
case let .success(response):
do {
let repos: [Repository]? = try response.map(toArray: Repository.self)
let repos: [Repository]? = try response.RmapArray(to: Repository.self)
if let repos = repos {
// Presumably, you'd parse the JSON into a model object. This is just a demo, so we'll keep it as-is.
self.repos = repos
Expand All @@ -26,10 +26,7 @@ class MoyaViewController: BaseViewController {
}
self.tableView.reloadData()
case let .failure(error):
guard let error = error as? CustomStringConvertible else {
break
}
message = error.description
message = (error as CustomStringConvertible).description
success = false
}

Expand Down
2 changes: 1 addition & 1 deletion EVReflection.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "EVReflection"
s.version = "5.0.0"
s.version = "5.0.3"
s.summary = "Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift"

s.description = <<-EOS
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,5 @@
breakpointStackSelectionBehavior = "1">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "UnitTests/MoyaTests/MoyaRxSwiftTests.swift"
timestampString = "528363609.45604"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "214"
endingLineNumber = "214"
landmarkName = "testNestedArray()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
73 changes: 64 additions & 9 deletions Source/Realm/RealmListEVCustomReflectable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,64 @@
import Foundation
import RealmSwift


extension Object : EVReflectable {
open override func setValue(_ value: Any?, forUndefinedKey key: String) {
self.addStatusMessage(.IncorrectKey, message: "The class '\(EVReflection.swiftStringFromClass(self))' is not key value coding-compliant for the key '\(key)'")

evPrint(.IncorrectKey, "WARNING: The class '\(EVReflection.swiftStringFromClass(self))' is not key value coding-compliant for the key '\(key)'\n❓ This could be a strange Realm List issue where tee key is reported undefined but it's still set.\n")
}
}

// We have to use custom reflection for a Realm object because Mirror often does not work.
extension Object: EVCustomReflectable {
/**
If you have a custom type that requires special conversion, then you can extend it with the EVCustomReflectable protocol.

- parameter value: The dictionary that will be converted to an object
*/
public func constructWith(value: Any?) {
if let jsonDict = value as? NSDictionary {
EVReflection.setPropertiesfromDictionary(jsonDict, anyObject: self)
}
}

/**
If you have a custom type that requires special conversion, then you can extend it with the EVCustomReflectable protocol.
Since Mirror does not work for a Realm Object we use the .value forKey

- returns: Dictionary without custom properties key
*/
public func toCodableValue() -> Any {
let dict: NSMutableDictionary = self.toDictionary() as! NSMutableDictionary
let newDict = NSMutableDictionary()

for (key, _) in dict {
let property: String = key as? String ?? ""
guard let value = self.value(forKey:property) else { continue }
if let detachable = value as? Object {
newDict.setValue(detachable.toCodableValue(), forKey: property)
} else if let detachable = value as? List {
let result = NSMutableArray()
detachable.forEach {
result.add($0.toCodableValue())
}
newDict.setValue(result, forKey: property)
} else {
newDict.setValue(value, forKey: property)
}
}
return dict
}
}

// We have to use custom reflection for a Realm list because Mirror often does not work.
extension List : EVCustomReflectable {
/**
If you have a custom type that requires special conversion, then you can extend it with the EVCustomReflectable protocol.

- parameter value: The dictionary that will be converted to an object
*/
public func constructWith(value: Any?) {
if let array = value as? [NSDictionary] {
self.removeAll()
Expand All @@ -20,6 +77,13 @@ extension List : EVCustomReflectable {
}
}
}

/**
If you have a custom type that requires special conversion, then you can extend it with the EVCustomReflectable protocol.
Since Mirror does not work for a Realm Object we use the .value forKey

- returns: Dictionary without custom properties key
*/
public func toCodableValue() -> Any {
var q = [NSDictionary]()
for case let e as Any in self {
Expand All @@ -31,12 +95,3 @@ extension List : EVCustomReflectable {
//return self.enumerated().map { ($0.element as? EVReflectable)?.toDictionary() ?? NSDictionary() }
}
}

extension Object : EVReflectable {

open override func setValue(_ value: Any?, forUndefinedKey key: String) {
self.addStatusMessage(.IncorrectKey, message: "The class '\(EVReflection.swiftStringFromClass(self))' is not key value coding-compliant for the key '\(key)'")

evPrint(.IncorrectKey, "\nWARNING: The class '\(EVReflection.swiftStringFromClass(self))' is not key value coding-compliant for the key '\(key)'\n")
}
}
1 change: 1 addition & 0 deletions UnitTests/EVReflectionTests/EVReflectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ class EVReflectionTests: XCTestCase {
let obj = A81c(json: json)
print(obj)
XCTAssert(obj.array.count == 1, "3 dimentional array should have 1 item")
// Failure should be fixed for https://github.com/evermeer/EVReflection/issues/212
XCTAssert(obj.array[0].count == 1, "3 dimentional array should have 1 item inside the first item")
XCTAssert(obj.array[0][0].count == 2, "3 dimentional array should have 2 items inside the first item of the first item")
// XCTAssert(obj.array[0][0][0].openId == "value1", "3 dimentional array should have 2 items inside the first item of the first item")
Expand Down
3 changes: 2 additions & 1 deletion UnitTests/RealmTests/RealmTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class RealmTests: XCTestCase {
let wife = Person(json: "{\"name\": \"Jennifer\", \"age\": \"47\", \"cars\": [{\"brand\": \"DeLorean\", \"name\": \"Outatime\", \"year\": 1981} , {\"brand\": \"Volkswagen\", \"year\": 2014}], \"spouse\": {\"name\": \"Marty\", \"age\": \"48\"}}")

// set the circular reference: The spouse of my spouse is me
wife.spouse?.spouse = wife
//Recursive objects in Realm will cause a crash!
// wife.spouse?.spouse = wife

// You will see _EVReflection_parent_ with the value 1 to indicate that there is a circular reference to it's parent 1 level up.
print("wife = \(wife.toJsonString())")
Expand Down

0 comments on commit 31e31df

Please sign in to comment.