Swift: Accessing JSON received by post request - ios

let task = URLSession.shared.dataTask(with: postRequest) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "NoData")
return
}
let jsonString = String(data: data, encoding: String.Encoding.utf8)!
self.submitView.text = jsonString
}
task.resume()
I'm trying to access the return value of this post request. I set a breakpoint and saw that jsonString does get the correct value. However, which I try to set self.submitView.text to anything, I get this error:
2017-06-21 14:20:16.062815-0400 Button[958:197756] This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
Stack:(
0 CoreFoundation 0x0000000191c82ff8 <redacted> + 148
1 libobjc.A.dylib 0x00000001906e4538 objc_exception_throw + 56
2 CoreFoundation 0x0000000191c82f28 <redacted> + 0
3 Foundation 0x0000000192874338 <redacted> + 128
4 Foundation 0x00000001926bc9f8 <redacted> + 36
5 UIKit 0x0000000197daf76c <redacted> + 816
6 UIKit 0x0000000197dbb668 <redacted> + 1740
7 UIKit 0x0000000197dbaf84 <redacted> + 828
8 UIKit 0x0000000197df90f4 <redacted> + 256
9 UIKit 0x0000000197df1818 <redacted> + 116
10 UIKit 0x00000001987ec308 <redacted> + 48
11 UIKit 0x0000000197e5d880 <redacted> + 280
12 UIFoundation 0x0000000197cdb238 <redacted> + 7012
13 UIFoundation 0x0000000197cdc0c8 <redacted> + 52
14 UIFoundation 0x0000000197d0eb70 <redacted> + 48
15 UIKit 0x0000000197e5d85c <redacted> + 244
16 UIFoundation 0x0000000197ce0214 <redacted> + 2172
17 UIFoundation 0x0000000197d0b058 <redacted> + 240
18 UIFoundation 0x0000000197d2f474 <redacted> + 160
19 UIFoundation 0x0000000197d2ebb4 <redacted> + 92
20 UIKit 0x0000000197e60500 <redacted> + 252
21 UIKit 0x0000000197e603e4 <redacted> + 196
22 Button 0x0000000100061e24 _TFFC6Button14ViewController12submitTappedFT_T_U_FTGSqV10Foundation4Data_GSqCSo11URLResponse_GSqPs5Error___T_ + 784
23 Button 0x0000000100062468 _TTRXFo_oGSqV10Foundation4Data_oGSqCSo11URLResponse_oGSqPs5Error____XFdCb_dGSqCSo6NSData_dGSqS1__dGSqCSo7NSError___ + 224
24 CFNetwork 0x000000019228c34c <redacted> + 32
25 CFNetwork 0x00000001922a4048 <redacted> + 148
26 Foundation 0x0000000192751814 <redacted> + 16
27 Foundation 0x0000000192696770 <redacted> + 96
28 Foundation 0x0000000192686b28 <redacted> + 612
29 Foundation 0x0000000192753bb0 <redacted> + 228
30 libdispatch.dylib 0x0000000100a6da10 _dispatch_client_callout + 16
31 libdispatch.dylib 0x0000000100a7b2e8 _dispatch_queue_serial_drain + 1140
32 libdispatch.dylib 0x0000000100a71634 _dispatch_queue_invoke + 852
33 libdispatch.dylib 0x0000000100a7d630 _dispatch_root_queue_drain + 552
34 libdispatch.dylib 0x0000000100a7d39c _dispatch_worker_thread3 + 140
35 libsystem_pthread.dylib 0x0000000190d43100 _pthread_wqthread + 1096
36 libsystem_pthread.dylib 0x0000000190d42cac start_wqthread + 4
)
2017-06-21 14:20:16.085280-0400 Button[958:197756] This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
Stack:(
0 CoreFoundation 0x0000000191c82ff8 <redacted> + 148
1 libobjc.A.dylib 0x00000001906e4538 objc_exception_throw + 56
2 CoreFoundation 0x0000000191c82f28 <redacted> + 0
3 Foundation 0x0000000192874338 <redacted> + 128
4 Foundation 0x00000001926bc9f8 <redacted> + 36
5 UIKit 0x0000000197eb18e0 <redacted> + 564
6 UIKit 0x0000000197db0138 <redacted> + 224
7 UIKit 0x0000000197daf8d0 <redacted> + 120
8 Foundation 0x00000001926bca7c <redacted> + 168
9 UIKit 0x0000000197daf76c <redacted> + 816
10 UIKit 0x0000000197dbb668 <redacted> + 1740
11 UIKit 0x0000000197dbaf84 <redacted> + 828
12 UIKit 0x0000000197df90f4 <redacted> + 256
13 UIKit 0x0000000197df1818 <redacted> + 116
14 UIKit 0x00000001987ec308 <redacted> + 48
15 UIKit 0x0000000197e5d880 <redacted> + 280
16 UIFoundation 0x0000000197cdb238 <redacted> + 7012
17 UIFoundation 0x0000000197cdc0c8 <redacted> + 52
18 UIFoundation 0x0000000197d0eb70 <redacted> + 48
19 UIKit 0x0000000197e5d85c <redacted> + 244
20 UIFoundation 0x0000000197ce0214 <redacted> + 2172
21 UIFoundation 0x0000000197d0b058 <redacted> + 240
22 UIFoundation 0x0000000197d2f474 <redacted> + 160
23 UIFoundation 0x0000000197d2ebb4 <redacted> + 92
24 UIKit 0x0000000197e60500 <redacted> + 252
25 UIKit 0x0000000197e603e4 <redacted> + 196
26 Button 0x0000000100061e24 _TFFC6Button14ViewController12submitTappedFT_T_U_FTGSqV10Foundation4Data_GSqCSo11URLResponse_GSqPs5Error___T_ + 784
27 Button 0x0000000100062468 _TTRXFo_oGSqV10Foundation4Data_oGSqCSo11URLResponse_oGSqPs5Error____XFdCb_dGSqCSo6NSData_dGSqS1__dGSqCSo7NSError___ + 224
28 CFNetwork 0x000000019228c34c <redacted> + 32
29 CFNetwork 0x00000001922a4048 <redacted> + 148
30 Foundation 0x0000000192751814 <redacted> + 16
31 Foundation 0x0000000192696770 <redacted> + 96
32 Foundation 0x0000000192686b28 <redacted> + 612
33 Foundation 0x0000000192753bb0 <redacted> + 228
34 libdispatch.dylib 0x0000000100a6da10 _dispatch_client_callout + 16
35 libdispatch.dylib 0x0000000100a7b2e8 _dispatch_queue_serial_drain + 1140
36 libdispatch.dylib 0x0000000100a71634 _dispatch_queue_invoke + 852
37 libdispatch.dylib 0x0000000100a7d630 _dispatch_root_queue_drain + 552
38 libdispatch.dylib 0x0000000100a7d39c _dispatch_worker_thread3 + 140
39 libsystem_pthread.dylib 0x0000000190d43100 _pthread_wqthread + 1096
40 libsystem_pthread.dylib 0x0000000190d42cac start_wqthread + 4
)
2017-06-21 14:20:16.088842-0400 Button[958:197756] *** Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *, UIView<NSTextContainerView> *, NSTextContainer *, NSUInteger)(), /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIFoundation/UIFoundation-491.7/UIFoundation/TextSystem/NSLayoutManager_Private.m:1577
2017-06-21 14:20:16.089727-0400 Button[958:197756] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!'
*** First throw call stack:
(0x191c82fe0 0x1906e4538 0x191c82eb4 0x19271a78c 0x197cd93f8 0x197cd90d8 0x197d07e88 0x197d0b188 0x197d2f474 0x197d2ebb4 0x197e60500 0x197e603e4 0x100061e24 0x100062468 0x19228c34c 0x1922a4048 0x192751814 0x192696770 0x192686b28 0x192753bb0 0x100a6da10 0x100a7b2e8 0x100a71634 0x100a7d630 0x100a7d39c 0x190d43100 0x190d42cac)
libc++abi.dylib: terminating with uncaught exception of type NSException
It seems like I can't assign self.submitView.text to anything inside the scope of "task". Any ideas why?
Edit:
Here is what the server returns upon sending a request.
"{\"raw\":\"schedule for John in New York on Monday\",\"location\":\"New York\",\"date\":\"Mon, June 26\",\"name\":\"john\",\"errorResponse\":null,\"stripTest\":\"for John in new york on Monday\"}"
This is what my code looks like:
do {
let info = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String : Any]
DispatchQueue.main.async {
self.submitView.text = info?["name"] as! String
}
} catch {
DispatchQueue.main.async {
self.submitView.text = "ERROR"
}
}
"ERROR" is no longer printing, but "info" seems to have 0 key/value pairs, thus nothing prints.
UPDATE:
print(try? JSONSerialization.jsonObject(with: data, options: [])) prints "nil"
The latter prints:
Optional("\"{\\\"raw\\\":\\\"Schedule for John in New York on Monday\\\",\\\"location\\\":\\\"new york\\\",\\\"date\\\":\\\"6/26/2017 12:00:00 AM\\\",\\\"name\\\":\\\"john\\\",\\\"errorResponse\\\":null,\\\"stripTest\\\":\\\" for john in new york on monday \\\"}\"")
This isn't what prints when I assign it to a text view in the UI.. is it converting the escape sequences to literal characters?

You are setting the text property of the UITextField on a background thread.
You need to ensure that all UI work is done on the main thread, You can do this using DispatchQueue...
DispatchQueue.main.async {
self.submitView.text = jsonString
}
Update:
The data is literally the data that was sent over the network, you will need to convert and deserialise it.
You can do this using the JSON Serialisation class like so:
// I create some dummy JSON string for example purposes
let data = "{ \"name\": \"John Smith\"}".data(using: String.Encoding.utf8)!
if let jsonObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:AnyObject] {
print(jsonObject["name"] as! String)
}
This tries to convert the data into a JSON object, which in Swift is usually cast to a dictionary object.
There are loads of resources on networking with Swift available. One I highly recommend would be iOS Networking with Swift this would take a fair bit of time to go through and learn so here is something that is alot quicker to get through Working with JSON in Swift
UPDATE
This code works for me:
let data = "{\"raw\":\"schedule for John in New York on Monday\",\"location\":\"New York\",\"date\":\"Mon, June 26\",\"name\":\"john\",\"errorResponse\":null,\"stripTest\":\"for John in new york on Monday\"}".data(using: String.Encoding.utf8)!
if let jsonObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:AnyObject] {
print(jsonObject)
print(jsonObject["name"] as! String)
}

Related

Where is the exclusivity violation in this Swift + CoreData view?

I'm a bit stumped on this one. I have two core data entities: Person and Memory. Memory has a people field that is a "to many" relationship to Person, and Person has a memories field that is a "to many" relationship to Memory.
I created a PeopleForm view to manage the people associated with a memory. The memory object gets passed in as an #ObservedObject to the view. I want to list the people, but people is an NSSet, so I created a computed property called peopleArray that converts the NSSet to [Person] (and sorts it for good measure).
I use the ForEach view with peopleArray to create a list of people. I use the onDelete view modifier to let the user remove a person from the list of people for that memory. The onDelete calls the removePerson function, which looks up the person object in peopleArray by the index, and then passes it to the memory object's removeFromPeople() method.
The removeFromPeople() method appears to be what triggers the runtime error. I've ready about exclusivity enforcement, but I can't figure out where I've gone wrong here.
The following is a pared down version of my code:
struct PeopleForm: View {
#ObservedObject var memory: Memory
#Environment(\.managedObjectContext) var viewContext
#Environment(\.dismiss) var dismiss
private var peopleArray: [Person] {
get {
Array(memory.people as! Set<Person>).sorted {
$0.displayName < $1.displayName
}
}
}
var body: some View {
NavigationView {
List {
ForEach(peopleArray) { person in
Text(person.displayName)
}
.onDelete(perform: removePerson)
}
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button("Save") {
dismiss()
}
}
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
dismiss()
}
}
}
}
}
func removePerson(at offsets: IndexSet) {
offsets.forEach { index in
let person = peopleArray[index]
viewContext.perform {
memory.removeFromPeople(person)
}
}
}
}
I also want to note that the stack trace points at the #main decorator on my App object declaration, which I understand is a symptom of a crash occurring within objc code. The error does not occur when stepping through the code line by line in the debugger, but I also can't step into the removeFromPeople method that is generated from my data model. If I step through to the removeFromPeople line and resume, the error occurs, so it seems to be something internal to CoreData that is going on here. Sure enough, the CoreData generated removeFromPeople method is objective c code for which I don't know how to see the implementation.
Simultaneous accesses to 0x117406ef0, but modification requires exclusive access.
Previous access (a modification) started at SwiftUI`<redacted> + 156 (0x198684c4c).
Current access (a read) started at:
0 libswiftCore.dylib 0x00000001957a59c8 <redacted> + 432
1 libswiftCore.dylib 0x00000001957a5bf0 swift_beginAccess + 84
2 SwiftUI 0x0000000198599250 <redacted> + 28
3 SwiftUI 0x000000019926b5e0 <redacted> + 44
4 SwiftUI 0x00000001985a5658 <redacted> + 124
5 SwiftUI 0x000000019937a078 <redacted> + 104
6 SwiftUI 0x000000019937a0fc <redacted> + 236
7 UIKitCore 0x0000000193e74fbc <redacted> + 124
8 UIKitCore 0x000000019329a428 <redacted> + 212
9 UIKitCore 0x00000001932e2fb4 <redacted> + 1100
10 UIKitCore 0x000000019310d2b0 <redacted> + 136
11 UIKitCore 0x0000000192f41030 <redacted> + 532
12 UIKitCore 0x0000000192f7015c <redacted> + 96
13 UIKitCore 0x000000019329aa58 <redacted> + 72
14 UIKitCore 0x0000000192fb6340 <redacted> + 436
15 SwiftUI 0x0000000198699f5c <redacted> + 64
16 SwiftUI 0x000000019865abf0 <redacted> + 16
17 libswiftCore.dylib 0x00000001957a83ec <redacted> + 56
18 SwiftUI 0x0000000198699f5c <redacted> + 64
19 SwiftUI 0x000000019865abf0 <redacted> + 16
20 libswiftCore.dylib 0x00000001957a83ec <redacted> + 56
21 SwiftUI 0x0000000198699f5c <redacted> + 64
22 SwiftUI 0x000000019865abf0 <redacted> + 16
23 libswiftCore.dylib 0x00000001957a83ec <redacted> + 56
24 libswiftCore.dylib 0x000000019579b060 swift_arrayDestroy + 124
25 SwiftUI 0x0000000198fe3c84 <redacted> + 44
26 SwiftUI 0x0000000198fe39ac <redacted> + 116
27 SwiftUI 0x00000001987883dc <redacted> + 40
28 libswiftCore.dylib 0x00000001957a83ec <redacted> + 56
29 AttributeGraph 0x00000001c2e76a70 <redacted> + 152
30 AttributeGraph 0x00000001c2e76178 <redacted> + 1260
31 AttributeGraph 0x00000001c2e75cc8 <redacted> + 264
32 SwiftUI 0x0000000198684bb0 <redacted> + 188
33 SwiftUI 0x00000001985cd1a0 <redacted> + 84
34 SwiftUI 0x00000001985c7758 _UIHostingView.__deallocating_deinit + 228
35 SwiftUI 0x00000001985d25ac <redacted> + 28
36 SwiftUI 0x0000000198718618 <redacted> + 36
37 libobjc.A.dylib 0x00000001a964027c <redacted> + 116
38 libobjc.A.dylib 0x00000001a963d0f4 objc_destructInstance + 80
39 libobjc.A.dylib 0x00000001a9646964 _objc_rootDealloc + 80
40 UIKitCore 0x00000001930be6c8 <redacted> + 156
41 UIKitCore 0x0000000192f89278 <redacted> + 1220
42 CoreFoundation 0x000000019095ebd4 <redacted> + 116
43 CoreFoundation 0x0000000190972848 <redacted> + 276
44 UIKitCore 0x0000000192f89278 <redacted> + 1184
45 UIKitCore 0x00000001931569bc <redacted> + 448
46 libobjc.A.dylib 0x00000001a963f9b0 <redacted> + 196
47 libobjc.A.dylib 0x00000001a963bd20 objc_autoreleasePoolPop + 212
48 UIKitCore 0x00000001930e8cf0 <redacted> + 92
49 UIKitCore 0x0000000192ffc008 <redacted> + 192
50 UIKitCore 0x0000000192f25664 <redacted> + 644
51 UIKitCore 0x0000000192f25f88 <redacted> + 132
52 UIKitCore 0x00000001932fe990 <redacted> + 84
53 UIKitCore 0x0000000193599030 <redacted> + 84
54 UIKitCore 0x0000000193c1ec20 <redacted> + 144
55 UIKitCore 0x0000000193c1e41c <redacted> + 92
56 CoreFoundation 0x0000000190a0bee8 <redacted> + 28
57 CoreFoundation 0x0000000190a1cbc0 <redacted> + 208
58 CoreFoundation 0x0000000190956078 <redacted> + 268
59 CoreFoundation 0x000000019095b810 <redacted> + 828
60 CoreFoundation 0x000000019096f460 CFRunLoopRunSpecific + 600
61 GraphicsServices 0x00000001aca092d0 GSEventRunModal + 164
62 UIKitCore 0x00000001932d4a3c <redacted> + 1100
63 UIKitCore 0x0000000193056480 UIApplicationMain + 364
64 SwiftUI 0x00000001987a659c <redacted> + 164
65 SwiftUI 0x00000001986d4428 <redacted> + 252
66 SwiftUI 0x00000001986b5790 static App.main() + 128
67 Matter 0x0000000104b657d8 static MatterApp.$main() + 40
68 Matter 0x0000000104b65938 main + 12
The design is not quite right. PeopleForm needs a #FetchRequest for People with an NSPredicate(format: "memory == %#", memory), e.g.
struct PeopleForm: View {
private var fetchRequest: FetchRequest<People>
private var people: FetchedResults< People > {
fetchRequest.wrappedValue
}
init(memory: Memory) {
let sortDescriptors = [SortDescriptor(\People.timestamp, order: sortAscending ? .forward : .reverse)]
fetchRequest = FetchRequest(sortDescriptors: sortDescriptors, predicate: NSPredicate(format: "memory = %#", memory), animation: .default)
}

NSInvalidArgumentException - Attempt to insert nil object from objects

I had the error below:
'*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1]'
it happens when I try to save texts from textfields using saveInBackground or other kind of saving method of Parse. Because code is little, all code is pasted below:
#IBAction func onSave(_ sender: Any) {
let profile = PFObject(className: "Info")
profile["preferredName"] = nameTextField.text!
profile["major"] = majorTextField.text!
profile["introduction"] = bioTextView.text!
let segmentIndex = yearSegmented.selectedSegmentIndex
UserDefaults.standard.set(segmentIndex, forKey: "segmentIndex")
profile["year"] = yearSegmented.titleForSegment(at: segmentIndex)!
print(profile.allKeys) // print keys in profile
print(profile.value(forKey: "introduction")!, profile.value(forKey: "major")!,
profile.value(forKey: "year")!, profile.value(forKey: "preferredName")!) // print values in profile
profile.saveInBackground(block: { (success, error) in // line where the error happens
if success {
UserDefaults.standard.set(true, forKey: "hasProfile")
print("profile saved")
} else {
print("failed to save profile")
}
})
This is how Parse IOS Guide told me about how to save objects:
let gameScore = PFObject(className:"GameScore")
gameScore["score"] = 1337
gameScore["playerName"] = "Sean Plott"
gameScore["cheatMode"] = false
gameScore.saveInBackground { (succeeded, error) in
if (succeeded) {
// The object has been saved.
} else {
// There was a problem, check error.description
}
}
I tested if any content in profile is nil, but all keys and values are there and can be printed. I don't see anything nil here, so I cannot understand this error. If anyone could shed some light to enlighten me, I would be be very grateful for this.
In case anyone needs the stack trace:
0 CoreFoundation 0x00000001803f25e4 __exceptionPreprocess + 236
1 libobjc.A.dylib 0x000000018019813c objc_exception_throw + 56
2 CoreFoundation 0x00000001804775b4 -[__NSCFString characterAtIndex:].cold.1 + 0
3 CoreFoundation 0x0000000180474fc4 -[__NSPlaceholderArray initWithCapacity:].cold.1 + 0
4 CoreFoundation 0x00000001802ef138 -[__NSPlaceholderArray initWithObjects:count:] + 184
5 CoreFoundation 0x00000001803dddec +[NSArray arrayWithObjects:count:] + 44
6 Parse 0x0000000104eda478 -[PFTaskQueue enqueue:] + 380
7 Parse 0x0000000104e78b2c -[PFObject saveInBackground] + 148
8 Parse 0x0000000104e78c1c -[PFObject saveInBackgroundWithBlock:] + 68
9 StudyMate 0x00000001041c59bc $s9StudyMate18EditViewControllerC6onSaveyyypF + 7276
10 StudyMate 0x00000001041c5fe4 $s9StudyMate18EditViewControllerC6onSaveyyypFTo + 68
11 UIKitCore 0x0000000184d81fa0 -[UIApplication sendAction:to:from:forEvent:] + 96
12 UIKitCore 0x00000001842a7714 -[UIBarButtonItem _triggerActionForEvent:] + 176
13 UIKitCore 0x000000018427fe24 __45-[_UIButtonBarTargetAction _invoke:forEvent:]_block_invoke + 36
14 UIKitCore 0x000000018427fcd8 -[_UIButtonBarTargetAction _invoke:forEvent:] + 168
15 UIKitCore 0x0000000184d81fa0 -[UIApplication sendAction:to:from:forEvent:] + 96
16 UIKitCore 0x0000000184680bd8 -[UIControl sendAction:to:forEvent:] + 124
17 UIKitCore 0x0000000184680fc0 -[UIControl _sendActionsForEvents:withEvent:] + 352
18 UIKitCore 0x0000000184681010 -[UIControl _sendActionsForEvents:withEvent:] + 432
19 UIKitCore 0x000000018467f8e8 -[UIControl touchesEnded:withEvent:] + 516
20 UIKitCore 0x0000000184dc0af0 -[UIWindow _sendTouchesForEvent:] + 1104
21 UIKitCore 0x0000000184dc25d4 -[UIWindow sendEvent:] + 4332
22 UIKitCore 0x0000000184d9a390 -[UIApplication sendEvent:] + 784
23 UIKitCore 0x0000000184e286f4 __dispatchPreprocessedEventFromEventQueue + 7520
24 UIKitCore 0x0000000184e2a770 __processEventQueue + 6764
25 UIKitCore 0x0000000184e22760 __eventFetcherSourceCallback + 184
26 CoreFoundation 0x0000000180360820 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
27 CoreFoundation 0x0000000180360720 __CFRunLoopDoSource0 + 204
28 CoreFoundation 0x000000018035fab0 __CFRunLoopDoSources0 + 256
29 CoreFoundation 0x000000018035a004 __CFRunLoopRun + 744
30 CoreFoundation 0x0000000180359804 CFRunLoopRunSpecific + 572
31 GraphicsServices 0x000000018c23660c GSEventRunModal + 160
32 UIKitCore 0x0000000184d7bd2c -[UIApplication _run] + 992
33 UIKitCore 0x0000000184d808c8 UIApplicationMain + 112
34 libswiftUIKit.dylib 0x00000001b6766224 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 100
35 StudyMate 0x00000001041c7a9c $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 104
36 StudyMate 0x00000001041c7a24 $s9StudyMate11AppDelegateC5$mainyyFZ + 44
37 StudyMate 0x00000001041c7b20 main + 28
38 dyld 0x0000000104501cd8 start_sim + 20
39 ??? 0x0000000104451088 0x0 + 4366602376
40 ??? 0xb23a000000000000 0x0 + 12842577287400390656

coder.decodeDouble causing crashes on app updates, value was previously an optional

I have an object that stores latitude and longitude coordinates. At one point, they were stored as an Optional Double?. I have since changed so it is a non optional Double. Now I see random crash logs from what I assume is users updating their app.
I tried checking to make sure that there is a value there, but it is still causing the crash.
let lat: Double
...
required init (coder aDecoder: NSCoder) {
...
if aDecoder.containsValue(forKey: "lat") {
lat = aDecoder.decodeDouble(forKey: "lat") //here is the crash
}else{
lat = 0
}
...
}
I previously came across this issue and used the following code to get around it, but Xcode says I cannot decode Doubles from objects any more
if let v = aDecoder.decodeObject(forKey: "lat") as? Double{//*** -[NSKeyedUnarchiver decodeObjectForKey:] : value for key ( lat ) is not an object. This will become an error in the future.
lat = v
}else{
if aDecoder.containsValue(forKey: "lat") {
lat = aDecoder.decodeDouble(forKey: "lat")
}else{
lat = 0
}
}
Here is a crash log:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Last Exception Backtrace:
0 CoreFoundation 0x18120004c __exceptionPreprocess + 220 (NSException.m:200)
1 libobjc.A.dylib 0x199874f54 objc_exception_throw + 60 (objc-exception.mm:565)
2 Foundation 0x182aa8e68 -[NSCoder __failWithException:] + 180 (NSCoder.m:0)
3 Foundation 0x182aa8fd4 -[NSCoder(Exceptions) __failWithExceptionName:errorCode:format:] + 260 (NSCoder.m:1191)
4 Foundation 0x182a4689c _decodeDouble + 660 (NSKeyedArchiver.m:0)
5 Foundation 0x1829bd3cc -[NSKeyedUnarchiver decodeDoubleForKey:] + 172 (NSKeyedArchiver.m:3918)
6 *Project* 0x102eefb98 specialized Location.init(coder:) + 1936 (Location.swift:145)
7 *Project* 0x102eed854 init + 4 (<compiler-generated>:0)
8 *Project* 0x102eed854 #objc Location.init(coder:) + 32
9 Foundation 0x1829c0268 _decodeObjectBinary + 2560 (NSKeyedArchiver.m:3058)
10 Foundation 0x1829a4a78 _decodeObject + 180 (NSKeyedArchiver.m:3324)
11 Foundation 0x1829c4304 -[NSKeyedUnarchiver decodeObjectForKey:] + 176 (NSKeyedArchiver.m:3344)
12 Foundation 0x182a272b8 +[NSKeyedUnarchiver unarchiveObjectWithData:] + 84 (NSKeyedArchiver.m:2390)
13 *Project* 0x102ee729c APS.loadOnDeckFromiCloud() + 240 (APS.swift:138)
14 *Project* 0x102ee7058 APS.().init() + 860 (APS.swift:105)
15 *Project* 0x102ee6ce8 one-time initialization function for SI + 40 (APS.swift:0)
16 libdispatch.dylib 0x180e72660 _dispatch_client_callout + 20 (object.m:560)
17 libdispatch.dylib 0x180e73f08 _dispatch_once_callout + 32 (once.c:52)
18 *Project* 0x102f3417c specialized DivertToOnboardingIfNeeded_VC.viewWillAppear(_:) + 1536 (APS.swift:97)
19 *Project* 0x102f334a8 viewWillAppear + 4 (<compiler-generated>:0)
20 *Project* 0x102f334a8 #objc DivertToOnboardingIfNeeded_VC.viewWillAppear(_:) + 28
21 UIKitCore 0x1837ba3e0 -[UIViewController _setViewAppearState:isAnimating:] + 664 (UIViewController.m:5522)
22 UIKitCore 0x1838e9004 -[UIViewController __viewWillAppear:] + 120 (UIViewController.m:5654)
23 UIKitCore 0x1838ba5b0 -[UINavigationController _startTransition:fromViewController:toViewController:] + 720 (UINavigationController.m:7329)
24 UIKitCore 0x183ae657c -[UINavigationController _startDeferredTransitionIfNeeded:] + 876 (UINavigationController.m:7494)
25 UIKitCore 0x1839bb6ac -[UINavigationController __viewWillLayoutSubviews] + 168 (UINavigationController.m:7806)
26 UIKitCore 0x1838e20f4 -[UILayoutContainerView layoutSubviews] + 228 (UILayoutContainerView.m:88)
27 UIKitCore 0x18379aed8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2620 (UIView.m:18347)
28 QuartzCore 0x184ef6e24 CA::Layer::layout_if_needed(CA::Transaction*) + 536 (CALayer.mm:10038)
29 QuartzCore 0x184ee9644 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 144 (CALayer.mm:2480)
30 QuartzCore 0x184efdc6c CA::Context::commit_transaction(CA::Transaction*, double, double*) + 524 (CAContextInternal.mm:2586)
31 QuartzCore 0x184f06560 CA::Transaction::commit() + 680 (CATransactionInternal.mm:449)
32 UIKitCore 0x183963f9c __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 44 (UIApplication.m:11470)
33 CoreFoundation 0x1811d9924 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28 (CFRunLoop.c:1820)
34 CoreFoundation 0x1811da820 __CFRunLoopDoBlocks + 412 (CFRunLoop.c:1862)
35 CoreFoundation 0x181172808 __CFRunLoopRun + 840 (CFRunLoop.c:2953)
36 CoreFoundation 0x1811863b8 CFRunLoopRunSpecific + 600 (CFRunLoop.c:3268)
37 GraphicsServices 0x19cb1638c GSEventRunModal + 164 (GSEvent.c:2200)
38 UIKitCore 0x183b266a8 -[UIApplication _run] + 1100 (UIApplication.m:3493)
39 UIKitCore 0x1838a57f4 UIApplicationMain + 2092 (UIApplication.m:5046)
40 *Project* 0x102e93388 main + 68 (MapBox_VC.swift:15)
41 dyld 0x103169a24 start + 520 (dyldMain.cpp:876)
How do I check the value stored in lat to make sure it is a Double ? (Non optional)

Understanding Firebase Crashlytics report for iOS app

I have an iOS app that uses Firebase Crashlytics for reporting crashes. Now I have a report for a crash but my problem is that I could not understand what exactly caused the crash from this report.
Crashlytics report:
Crashed: com.apple.main-thread
0 Nail it 0x104db77a8 CaseDetailsViewController.getbaseData() + 253
(CaseDetailsViewController.swift:253)
1 Nail it 0x104db5168 CaseDetailsViewController.viewDidLoad() + 4335047016 (<compiler-generated>:4335047016)
2 Nail it 0x104db521c #objc CaseDetailsViewController.viewDidLoad() + 4335047196 (<compiler-generated>:4335047196)
3 UIKitCore 0x185d11658 -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 100
4 UIKitCore 0x185d160e8 -[UIViewController loadViewIfRequired] + 936
5 UIKitCore 0x185d164f0 -[UIViewController view] + 28
6 UIKit 0x1b913374c -[UIViewControllerAccessibility dismissViewControllerWithTransition:completion:] + 268
7 UIKitCore 0x185d28d6c -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 508
8 UIKitCore 0x185d2b474 -[UIViewController dismissViewControllerAnimated:completion:] + 132
9 UIKit 0x1b91333c0 -[UIViewControllerAccessibility dismissViewControllerAnimated:completion:] + 120
10 Nail it 0x104db98ec #objc CaseDetailsViewController.backButton(_:) + 4335065324 (<compiler-generated>:4335065324)
11 UIKitCore 0x18635a72c -[UIApplication sendAction:to:from:forEvent:] + 96
12 UIKitCore 0x185a05474 __45-[_UIButtonBarTargetAction _invoke:forEvent:]_block_invoke + 80
13 UIKitCore 0x185a05304 -[_UIButtonBarTargetAction _invoke:forEvent:] + 236
14 UIKitCore 0x18635a72c -[UIApplication sendAction:to:from:forEvent:] + 96
15 UIKitCore 0x185d6aed0 -[UIControl sendAction:to:forEvent:] + 240
16 UIKitCore 0x185d6b228 -[UIControl _sendActionsForEvents:withEvent:] + 396
17 UIKitCore 0x185d6a24c -[UIControl touchesEnded:withEvent:] + 516
18 UIKitCore 0x18639449c -[UIWindow _sendTouchesForEvent:] + 1280
19 UIKitCore 0x186395c64 -[UIWindow sendEvent:] + 3468
20 UIKitCore 0x1863718ec -[UIApplication sendEvent:] + 344
21 UIKit 0x1b90db80c -[UIApplicationAccessibility sendEvent:] + 96
22 UIKitCore 0x1863f2970 __dispatchPreprocessedEventFromEventQueue + 6808
23 UIKitCore 0x1863f54ec __handleEventQueueInternal + 5364
24 UIKitCore 0x1863ed168 __handleHIDEventFetcherDrain + 140
25 CoreFoundation 0x182223ad8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
26 CoreFoundation 0x182223a30 __CFRunLoopDoSource0 + 80
27 CoreFoundation 0x1822231b8 __CFRunLoopDoSources0 + 184
28 CoreFoundation 0x18221e1e8 __CFRunLoopRun + 788
29 CoreFoundation 0x18221dba8 CFRunLoopRunSpecific + 424
30 GraphicsServices 0x18c394344 GSEventRunModal + 160
31 UIKitCore 0x1863593e4 UIApplicationMain + 1932
32 Nail it 0x104d797cc main + 16 (AppDelegate.swift:16)
33 libdyld.dylib 0x1820a58f0 start + 4
Below is the function getBaseData() from CasesDetails View Controller:
func getbaseData(){
let userDefaults = UserDefaults.standard
mobile = userDefaults.value(forKey: "mobile") as! String
altenativeMobile = userDefaults.string(forKey: "altenativeMobile") ?? mobile
privateKey = userDefaults.value(forKey: "privateKey") as! String
////reading JSON
let categoriesJsonString = userDefaults.value(forKey: "categoriesString") as! String
let data = categoriesJsonString.data(using: .utf8)!
if let json = try? JSON(data: data) {
let arrayCats = json["content"][1]["caseMappings"][caseCategoryGlobal].array
if(isNoSubsGlob == 0){
if let arrayCatsCount = arrayCats?.count {
print("The array has been created with \(arrayCatsCount) element")
print("sub1Glob= \(sub1Glob) & sub2Glob= \(sub2Glob)")
for var i in 0..<arrayCatsCount{
let sub1 = json["content"][1]["caseMappings"][caseCategoryGlobal][i]["sub1"].string!
let sub2 = json["content"][1]["caseMappings"][caseCategoryGlobal][i]["sub2"].string ?? ""
if (sub1 == sub1Glob && sub2 == sub2Glob){
departmentId = json["content"][1]["caseMappings"][caseCategoryGlobal][i]["departmentId"].int!
WorkTypeId = json["content"][1]["caseMappings"][caseCategoryGlobal][i]["categoryId"].int!
issueCode = json["content"][1]["caseMappings"][caseCategoryGlobal][i]["id"].int!
}
}
}
}else{
departmentId = json["content"][1]["caseMappings"][caseCategoryGlobal][0]["departmentId"].int!
WorkTypeId = json["content"][1]["caseMappings"][caseCategoryGlobal][0]["categoryId"].int!
issueCode = json["content"][1]["caseMappings"][caseCategoryGlobal][0]["id"].int!
}
}
contactNumberText.text = altenativeMobile
}
and the line 235 is (contactNumberText.text = altenativeMobile) as the last line in the code above
All UI stuff should be performed on main thread, that is what your crash report shows (crash due to main thread.)
So your last line should be :
DispatchQueue.main.async {
self.contactNumberText.text = altenativeMobile
}
Update this line, your crash will fixed.

Fatal Exception: NSInvalidArgumentException while working with UISwitch in UITableview

AppName denotes the application name.
User reported this crash. It only came once and also not able to reproduce the same on my end. Hence not able to debug. If some one can provide some insight for the same.
Below is the Crashlytics log received.
# OS Version: 12.4.2 (16G114)
# Device: iPhone 5s
# RAM Free: 8.5%
# Disk Free: 9.6%
#0. Crashed: com.twitter.crashlytics.ios.exception
0 App Name 0x100df7388 CLSProcessRecordAllThreads + 376 (CLSProcess.c:376)
1 App Name 0x100df7770 CLSProcessRecordAllThreads + 407 (CLSProcess.c:407)
2 App Name 0x100de7474 CLSHandler + 26 (CLSHandler.m:26)
3 App Name 0x100df599c __CLSExceptionRecord_block_invoke + 198 (CLSException.mm:198)
4 libdispatch.dylib 0x1db6217d4 _dispatch_client_callout + 16
5 libdispatch.dylib 0x1db5cfc1c _dispatch_lane_barrier_sync_invoke_and_complete + 56
6 App Name 0x100df5444 CLSExceptionRecord + 205 (CLSException.mm:205)
7 App Name 0x100df5278 CLSExceptionRecordNSException + 102 (CLSException.mm:102)
8 App Name 0x100df4e9c CLSTerminateHandler() + 258 (CLSException.mm:258)
9 libc++abi.dylib 0x1dadb0838 std::__terminate(void (*)()) + 16
10 libc++abi.dylib 0x1dadb0434 __cxa_rethrow + 144
11 libobjc.A.dylib 0x1dadbbbc8 objc_exception_rethrow + 44
12 CoreFoundation 0x1dbb72030 CFRunLoopRunSpecific + 544
13 GraphicsServices 0x1ddd7379c GSEventRunModal + 104
14 UIKitCore 0x2084f3c38 UIApplicationMain + 212
15 App Name 0x100c1ee1c main + 23 (ViewController.swift:23)
16 libdyld.dylib 0x1db6328e0 start + 4
--
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x1dbbe6190 __exceptionPreprocess
1 libobjc.A.dylib 0x1dadbb9f8 objc_exception_throw
2 CoreFoundation 0x1dbaf03b0 -[NSCache init]
3 CFNetwork 0x1dc3f4b58 -[NSURLSessionTask cancel]
4 App Name 0x100cb9fec ViewController.switchChanged(_:) (ViewController.swift)
5 App Name 0x100cbac7c #objc ViewController.switchChanged(_:) (<compiler-generated>)
6 UIKitCore 0x2084f5300 -[UIApplication sendAction:to:from:forEvent:]
7 UIKitCore 0x207f9e424 -[UIControl sendAction:to:forEvent:]
8 UIKitCore 0x207f9e744 -[UIControl _sendActionsForEvents:withEvent:]
9 UIKitCore 0x207fcb0fc -[UISwitchModernVisualElement sendStateChangeActions]
10 UIKitCore 0x207fcaa04 -[UISwitchMVEGestureTrackingSession _sendStateChangeActionsIfNecessary]
11 UIKitCore 0x207fcb7a4 -[UISwitchModernVisualElement _handleLongPressWithGestureLocationInBounds:gestureState:]
12 UIKitCore 0x20811cac4 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:]
13 UIKitCore 0x208124ccc _UIGestureRecognizerSendTargetActions
14 UIKitCore 0x208122670 _UIGestureRecognizerSendActions
15 UIKitCore 0x208121b9c -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:]
16 UIKitCore 0x208115c78 _UIGestureEnvironmentUpdate
17 UIKitCore 0x2081153a8 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:]
18 UIKitCore 0x208115188 -[UIGestureEnvironment _updateForEvent:window:]
19 UIKitCore 0x20852d7d0 -[UIWindow sendEvent:]
20 UIKitCore 0x20850d85c -[UIApplication sendEvent:]
21 UIKitCore 0x2085d39d4 __dispatchPreprocessedEventFromEventQueue
22 UIKitCore 0x2085d6100 __handleEventQueueInternal
23 UIKitCore 0x2085cf330 __handleHIDEventFetcherDrain
24 CoreFoundation 0x1dbb77f2c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
25 CoreFoundation 0x1dbb77eac __CFRunLoopDoSource0
26 CoreFoundation 0x1dbb77794 __CFRunLoopDoSources0
27 CoreFoundation 0x1dbb726d0 __CFRunLoopRun
28 CoreFoundation 0x1dbb71fc4 CFRunLoopRunSpecific
29 GraphicsServices 0x1ddd7379c GSEventRunModal
30 UIKitCore 0x2084f3c38 UIApplicationMain
31 App Name 0x100c1ee1c main + 23 (ViewController.swift:23)
32 libdyld.dylib 0x1db6328e0 start
Below is some part of code which may give more clear picture.
case .SettingsCell:
let cell: SettingsCell = tableView.dequeueReusableCell(withIdentifier: "SettingsCell") as! SettingsCell
cell.selectionStyle = .none
cell.switchOnOff.addTarget(self, action: #selector(switchChanged(_ :)), for: .valueChanged)
Below is the function called on UISwitch button value change.
case 13:
if sender.isOn{
UserDefaultUtility.saveToUserDefault(value: true, key: Constant.UserDefaults.k_IsAnimation)
appDelegate.getPollutantAbbreviationAndGIFImages()
} else {
let networkManager = NetworkManager()
networkManager.cancelImageDownloadTask()
}
Below is the function in Network Manager:
func cancelImageDownloadTask() {
self.downloadImagesSession?.cancel()
}
Download session is URLSessionDownloadTask object declared below.
weak var downloadImagesSession: URLSessionDownloadTask?
It is allocated using below code.
self.downloadImagesSession = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
}
That seems to be the problem:
let networkManager = NetworkManager()
networkManager.cancelImageDownloadTask()
You just initialize a NetworkManager instance, and then directly try to cancel a task. But you cannot cancel a task which isn't started yet

Resources