Skip to content

Commit

Permalink
Use map instead of flatMap when parsing
Browse files Browse the repository at this point in the history
`JSONValue.parse` returns a non-optional `JSONValue`. Unfortunately,
because of Swift Magic, Xcode will happily compile when using `flatMap`
with a function that returns a non-optional. This can (but doesn't
always) result in a EXC_BAD_ACCESS error at runtime. Using `map` here is
actually the correct behavior, but should also fix this crash that
people were seeing.
  • Loading branch information
gfontenot committed Jan 14, 2015
1 parent 6a541c2 commit 7a522a5
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Argo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
F862E0AC1A519D520093B028 /* post_comments.json in Resources */ = {isa = PBXBuildFile; fileRef = EA08313219D5EEF2003B90D7 /* post_comments.json */; };
F862E0AD1A519D560093B028 /* types.json in Resources */ = {isa = PBXBuildFile; fileRef = EA08313419D5EFC0003B90D7 /* types.json */; };
F862E0AE1A519D5C0093B028 /* types_fail_embedded.json in Resources */ = {isa = PBXBuildFile; fileRef = EA4EAF7219DD96330036AE0D /* types_fail_embedded.json */; };
F874B7EA1A66BF52004CCE5E /* root_array.json in Resources */ = {isa = PBXBuildFile; fileRef = F874B7E91A66BF52004CCE5E /* root_array.json */; };
F874B7EB1A66C221004CCE5E /* root_array.json in Resources */ = {isa = PBXBuildFile; fileRef = F874B7E91A66BF52004CCE5E /* root_array.json */; };
F893355F1A4CE83000B88685 /* Argo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F89335541A4CE83000B88685 /* Argo.framework */; };
F893356E1A4CE8FC00B88685 /* Argo.h in Headers */ = {isa = PBXBuildFile; fileRef = F893356D1A4CE8FC00B88685 /* Argo.h */; settings = {ATTRIBUTES = (Public, ); }; };
F893356F1A4CE8FC00B88685 /* Argo.h in Headers */ = {isa = PBXBuildFile; fileRef = F893356D1A4CE8FC00B88685 /* Argo.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -149,6 +151,7 @@
EADADCB11A5DB6F600B180EC /* EquatableSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EquatableSpec.swift; sourceTree = "<group>"; };
F802D4C21A5EE061005E236C /* NSURL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSURL.swift; sourceTree = "<group>"; };
F802D4C51A5EE2D5005E236C /* url.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = url.json; sourceTree = "<group>"; };
F874B7E91A66BF52004CCE5E /* root_array.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = root_array.json; sourceTree = "<group>"; };
F89335541A4CE83000B88685 /* Argo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Argo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F893355E1A4CE83000B88685 /* Argo-MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Argo-MacTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
F893356D1A4CE8FC00B88685 /* Argo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Argo.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -309,6 +312,7 @@
EAD9FB0419D2143A0031E006 /* user_with_email.json */,
EAD9FB0819D214AA0031E006 /* user_without_email.json */,
F802D4C51A5EE2D5005E236C /* url.json */,
F874B7E91A66BF52004CCE5E /* root_array.json */,
EAD9FB0919D214AA0031E006 /* TemplateIcon2x.png */,
EAD9FB1319D30ED00031E006 /* comment.json */,
EAD9FB1519D30F8D0031E006 /* post_no_comments.json */,
Expand Down Expand Up @@ -506,6 +510,7 @@
EA08313519D5EFC0003B90D7 /* types.json in Resources */,
EA4EAF7319DD96330036AE0D /* types_fail_embedded.json in Resources */,
EA395DCA1A52FC1400EB607E /* root_object.json in Resources */,
F874B7EA1A66BF52004CCE5E /* root_array.json in Resources */,
EAD9FB1619D30F8D0031E006 /* post_no_comments.json in Resources */,
EA08313319D5EEF2003B90D7 /* post_comments.json in Resources */,
EAD9FB0A19D214AA0031E006 /* user_without_email.json in Resources */,
Expand All @@ -532,6 +537,7 @@
F862E0AD1A519D560093B028 /* types.json in Resources */,
F862E0AE1A519D5C0093B028 /* types_fail_embedded.json in Resources */,
EA395DCB1A52FC1400EB607E /* root_object.json in Resources */,
F874B7EB1A66C221004CCE5E /* root_array.json in Resources */,
F8EF75711A4CEC7100BDCC2D /* post_no_comments.json in Resources */,
F862E0AC1A519D520093B028 /* post_comments.json in Resources */,
F8EF756E1A4CEC7100BDCC2D /* user_without_email.json in Resources */,
Expand Down
2 changes: 1 addition & 1 deletion Argo/Globals/JSONValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public extension JSONValue {
case let v as [String: AnyObject]:
let object = reduce(v.keys, JSONDict()) { accum, key in
let append = curry(Dictionary.appendKey)(accum)(key)
return (append <^> v[key] >>- self.parse) ?? append(.JSONNull)
return (append <^> (self.parse <^> v[key])) ?? append(.JSONNull)
}
return .JSONObject(object)

Expand Down
10 changes: 10 additions & 0 deletions ArgoTests/JSON/root_array.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"title": "Foo",
"age": 21
},
{
"title": "Bar",
"age": 32
}
]
8 changes: 8 additions & 0 deletions ArgoTests/Tests/ExampleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,12 @@ class ExampleTests: XCTestCase {
XCTAssert(url != nil)
XCTAssert(url?.absoluteString == "http://example.com")
}

func testDecodingJSONWithRootArray() {
let expected = JSONValue.parse([["title": "Foo", "age": 21], ["title": "Bar", "age": 32]])
let json: AnyObject? = JSONFileReader.JSON(fromFile: "root_array")
let parsed = json >>- JSONValue.parse

XCTAssert(.Some(expected) == parsed)
}
}

0 comments on commit 7a522a5

Please sign in to comment.