在 Swift 中写入 JSON 中的***类型无效
Posted
技术标签:
【中文标题】在 Swift 中写入 JSON 中的***类型无效【英文标题】:Invalid top-level type in JSON write in Swift 【发布时间】:2014-11-27 09:05:34 【问题描述】:我正在尝试使用 AFNetworking 进行 PUT。我需要在比赛中发送一组参与者,但我收到“用 Swift 编写的 JSON 中的***类型无效”错误。我生成的 JSON 是完美的,如果我使用 REST 客户端尝试它,一切正常。这是我的代码:
func sendUsers(onComplete: (NSError?) -> Void)
var error: NSError?
var jsonData: NSData = NSJSONSerialization.dataWithJSONObject(self.createDictionaryOfParticipations(), options: NSJSONWritingOptions.allZeros, error: &error)!
var jsonString: String = NSString(data: jsonData, encoding: NSUTF8StringEncoding)!
println("Json: \(jsonString)")
if self.requestManager == nil
self.requestManager = AFHTTPRequestOperationManager();
self.requestManager?.responseSerializer = AFJSONResponseSerializer();
let requestSerializer = AFJSONRequestSerializer()
self.requestManager?.requestSerializer = requestSerializer;
self.requestManager?.requestSerializer.setValue("application/json", forHTTPHeaderField: "Content-Type");
self.requestManager?.PUT(kParticipantsUrl, parameters: jsonString, success: (operation: AFHTTPRequestOperation!, object: AnyObject!) -> Void in
self.persistUsers([])
onComplete(nil)
, failure: (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
onComplete(error)
)
我创建 JSONObject 中的方法:
func createDictionaryOfParticipations() -> NSArray
var dict: NSMutableDictionary = NSMutableDictionary()
var participants: NSMutableArray = NSMutableArray()
var savedParticipants: [User] = self.getUsers() as [User]
for participant: User in savedParticipants
var participantDict: NSMutableDictionary = NSMutableDictionary()
participantDict.setValue(participant.name, forKey: kNameKey)
participantDict.setValue(participant.firstSurname, forKey: kFirstSurnameKey)
participantDict.setValue(participant.secondSurname, forKey: kSecondSurnameKey)
participantDict.setValue(participant.dni, forKey: kDniKey)
participantDict.setValue(participant.address, forKey: kAddressKey)
participantDict.setValue(participant.postalCode, forKey: kPostalCodeKey)
participantDict.setValue(participant.city, forKey: kCityKey)
participantDict.setValue(participant.province, forKey: kProvinceKey)
participantDict.setValue(participant.phone, forKey: kPhoneKey)
participantDict.setValue(participant.email, forKey: kEmailKey)
participantDict.setValue(participant.code, forKey: kCodeKey)
participantDict.setValue(participant.prize, forKey: kPrizeKey)
participants.addObject(participantDict)
return participants
如果我运行应用程序并发送请求,我会收到以下错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'
*** First throw call stack:
(
0 CoreFoundation 0x0000000103b5df35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001037f6bb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000103b5de6d +[NSException raise:format:] + 205
3 Foundation 0x000000010349b0ea +[NSJSONSerialization dataWithJSONObject:options:error:] + 264
4 MLB 0x00000001031cb23c -[AFJSONRequestSerializer requestBySerializingRequest:withParameters:error:] + 1164
5 MLB 0x00000001031c13bd -[AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:] + 1869
6 MLB 0x00000001031e6d14 -[AFHTTPRequestOperationManager PUT:parameters:success:failure:] + 388
7 MLB 0x000000010317acf0 _TFC3MLB12UsersManager9sendUsersfS0_FFGSqCSo7NSError_T_T_ + 8656
8 MLB 0x0000000103166426 _TFC3MLB22MainMenuViewController9alertViewfS0_FTCSo11UIAlertView20clickedButtonAtIndexSi_T_ + 630
9 MLB 0x0000000103166602 _TToFC3MLB22MainMenuViewController9alertViewfS0_FTCSo11UIAlertView20clickedButtonAtIndexSi_T_ + 66
10 UIKit 0x00000001046773e0 -[UIAlertView _prepareToDismissForTappedIndex:] + 161
11 UIKit 0x0000000104676ede __35-[UIAlertView _prepareAlertActions]_block_invoke50 + 43
12 UIKit 0x0000000104670464 -[UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:] + 89
13 UIKit 0x00000001047c6540 _UIGestureRecognizerUpdate + 9487
14 UIKit 0x000000010445eff6 -[UIWindow _sendGesturesForEvent:] + 1041
15 UIKit 0x000000010445fc23 -[UIWindow sendEvent:] + 667
16 UIKit 0x000000010442c9b1 -[UIApplication sendEvent:] + 246
17 UIKit 0x0000000104439a7d _UIApplicationHandleEventFromQueueEvent + 17370
18 UIKit 0x0000000104415103 _UIApplicationHandleEventQueue + 1961
19 CoreFoundation 0x0000000103a93551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
20 CoreFoundation 0x0000000103a8941d __CFRunLoopDoSources0 + 269
21 CoreFoundation 0x0000000103a88a54 __CFRunLoopRun + 868
22 CoreFoundation 0x0000000103a88486 CFRunLoopRunSpecific + 470
23 GraphicsServices 0x00000001084ca9f0 GSEventRunModal + 161
24 UIKit 0x0000000104418420 UIApplicationMain + 1282
25 MLB 0x000000010319f84e top_level_code + 78
26 MLB 0x000000010319f88a main + 42
27 libdyld.dylib 0x000000010679c145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
我不知道问题出在哪里...我放入 JSON 中的属性的对象是 NSObject,我放入 json 中的所有字段都是字符串(字符串类型,而不是 NSString),我尝试过使用 NSString 但我仍然得到错误。有任何想法吗??谢谢
【问题讨论】:
【参考方案1】:您自己进行 JSON 序列化,然后要求 AFN 再做一次,因此您传递了一个 NSString
并要求将其序列化为 JSON,但这是行不通的。
您应该做的是传递从createDictionaryOfParticipations
返回的NSArray
:
self.requestManager?.PUT(kParticipantsUrl, parameters: self.createDictionaryOfParticipations(), success:...
【讨论】:
酷,但现在我得到了这个错误:Error Domain=NSCocoaErrorDomain Code=3840 “操作无法完成。(Cocoa 错误 3840。)”(JSON 文本没有以数组或对象开头和允许未设置片段的选项。) UserInfo=0x7fdee3753d10 NSDebugDescription=JSON 文本没有以数组或对象开头,并且允许未设置片段的选项。 堆栈跟踪在哪里?您似乎在这里寻求基本调试方面的帮助。 好的,现在完全解决了,最后一个错误是因为 web 服务没有返回任何内容,现在它返回“成功”并且一切正常。谢谢韦恩!以上是关于在 Swift 中写入 JSON 中的***类型无效的主要内容,如果未能解决你的问题,请参考以下文章
Swift 中 JSON 写入(NSConcreteMutableData)中的类型无效
如何使用与 NewtonSoft (JSON.Net) 组件中的 JSON 匹配的 Swift 类从/向 JSON 读取/写入对象数组?