MacGapProject / MacGap1

Desktop WebKit wrapper for HTML/CSS/JS applications.
Other
3.55k stars 209 forks source link

Invalid type in JSON write (__NSCFData)? #106

Open samowitsch opened 10 years ago

samowitsch commented 10 years ago

Hi, i cloned macgap and when i compile the unmodified project and resize or move the window of the macgap app to another position i get an error? What i am doing wrong? Window resizing is not possible?

2014-04-24 22:45:47.591 MacGap[9549:303] Invalid type in JSON write (NSCFData) 2014-04-24 22:45:47.593 MacGap[9549:303] 0 CoreFoundation 0x00007fff98a9e25c exceptionPreprocess + 172 1 libobjc.A.dylib 0x00007fff99cb5e75 objc_exception_throw + 43 2 CoreFoundation 0x00007fff98a9e10c +[NSException raise:format:] + 204 3 Foundation 0x00007fff93b36f06 writeJSONValue + 719 4 Foundation 0x00007fff93b3ae39 writeJSONObject_block_invoke + 214 5 CoreFoundation 0x00007fff989d3ddc __NSDictionaryEnumerate_block_invoke412 + 28 6 CoreFoundation 0x00007fff989929ac CFBasicHashApply + 124 7 CoreFoundation 0x00007fff989d3c7b NSDictionaryEnumerate + 587 8 Foundation 0x00007fff93b3aa39 _writeJSONObject + 397 9 Foundation 0x00007fff93b36e26 _writeJSONValue + 495 10 Foundation 0x00007fff93b36c02 -[_NSJSONWriter dataWithRootObject:options:error:] + 129 11 Foundation 0x00007fff93b3934a +[NSJSONSerialization dataWithJSONObject:options:error:] + 337 12 MacGap 0x000000010000c43f +[JSEventHelper triggerEvent:withArgs:forObject:forWebView:] + 191 13 MacGap 0x000000010000c33c +[JSEventHelper triggerEvent:withArgs:forWebView:] + 172 14 MacGap 0x000000010000883b -[UserDefaults defaultsChanged:] + 187 15 CoreFoundation 0x00007fff98a6ce0c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 12 16 CoreFoundation 0x00007fff989608dd _CFXNotificationPost + 2893 17 Foundation 0x00007fff939437ba -[NSNotificationCenter postNotificationName:object:userInfo:] + 68 18 AppKit 0x00007fff92eca3da -[NSWindow _setFrame:updateBorderViewSize:] + 395 19 AppKit 0x00007fff93058acf -[NSWindow _setFrameAfterMove:] + 370 20 AppKit 0x00007fff9302e140 -[NSWindow _windowMovedToRect:] + 627 21 AppKit 0x00007fff93058947 -[NSWindow _windowMoved:] + 159 22 AppKit 0x00007fff92faadb1 -[NSWindow sendEvent:] + 3721 23 AppKit 0x00007fff92f4b82b -[NSApplication sendEvent:] + 2348 24 AppKit 0x00007fff92d9bb89 -[NSApplication run] + 646 25 AppKit 0x00007fff92d86913 NSApplicationMain + 940 26 MacGap 0x0000000100007302 main + 34 27 libdyld.dylib 0x00007fff8e0bb5fd start + 1

samowitsch commented 10 years ago

This exception appears at the "userDefaultsChanged" event. Inside the args (NSDictionary) is a lot of Apple stuff. It seems that some parts of it can't serialized to Json?

jeff-h commented 10 years ago

Grrr — your last comment is almost certainly correct. Thanks for the heads-up.

For me, everything in my NSUserDefaults was able to be serialised. It seems I was too presumptuous that this implied everyone's NSUserDefaults would therefore also be able to be serialised.

I'll have to change it so that only a subset is passed through to JavaScript. The easy solution would be just keys beginning with macgap_ but I did feel that there was a bunch of other potentially useful info in the NSUserDefaults. I'll see if I can get more info through as well as just the magcap_ stuff.

jeff-h commented 10 years ago

Quick question — are you familiar with Xcode's debugger output? If so, could you tell me if you got the following message in it?

Got an error converting to JSON

samowitsch commented 10 years ago

I never see this NSLog message. Portion out of Frameworks/Foundation/NSJSONSerialization.h comments: "... If the object will not produce valid JSON then an exception will be thrown..."

As a workaround to get things running i inserted at some points: if([NSJSONSerialization isValidJSONObject:args] == YES){ //NSUserDefaults stuff in JSEventHelper.m / UserDefaults.m / Utils.m }

But i think this is no good solution :-)

jeff-h commented 10 years ago

I've just committed a fix for this situation; I removed getUserDefaults and replaced it with getMyDefaults, to ensure we only ever return those values we previously set ourselves (and can thus be confident of their data type).

Could you have a try when you get a chance and see if the changes are working for you?

jeff-h commented 10 years ago

I actually like the sound of your suggested NSJSONSerialization isValidJSONObject check, especially in Utils convertDictionaryToJSON. Can I ask why you think it's not a good solution?

samowitsch commented 10 years ago

The check itself is good. What i don't like is that one UserDefault object prevents to get all the other interesting stuff. But at this point it is maybe better to write a custom conversion.

Your last commits are working for me.

jeff-h commented 10 years ago

What I don't understand is why NSJSONSerialization seems to be all-or-nothing. I think a partial-serialisation of the UserDefault object would still be useful (omitting just those items that can't be serialised).

Do you think we should go through each of the keys of the Dictionary and check NSJSONSerialization isValidJSONObject for each value in turn, and if it passes then add that key-value to a new dictionary which ends up being serialised?

samowitsch commented 10 years ago

I think this would be a good solution.