如果您想了解具有多维和多类型数组的Swift4JSON可解码的相关知识,那么本文是一篇不可错过的文章,我们将对json多维数组格式进行全面详尽的解释,并且为您提供关于2.9多维数组的创建和遍历[Swi
如果您想了解具有多维和多类型数组的Swift 4 JSON可解码的相关知识,那么本文是一篇不可错过的文章,我们将对json多维数组 格式进行全面详尽的解释,并且为您提供关于2.9 多维数组的创建和遍历 [Swift原创教程]、ios – Swift:从接口类型数组转换为对象数组崩溃、ios – Swift:使用Alamofire和SwiftyJSON处理JSON、json – Swift 4可解码,带有未知的动态键的有价值的信息。
本文目录一览:- 具有多维和多类型数组的Swift 4 JSON可解码(json多维数组 格式)
- 2.9 多维数组的创建和遍历 [Swift原创教程]
- ios – Swift:从接口类型数组转换为对象数组崩溃
- ios – Swift:使用Alamofire和SwiftyJSON处理JSON
- json – Swift 4可解码,带有未知的动态键
具有多维和多类型数组的Swift 4 JSON可解码(json多维数组 格式)
{"values":[[1,1,7,"Azuan Child","Anak Azuan","12345","ACTIVE","Morning",7,12,"2017-11-09 19:45:00"],[28,1,0,"Azuan Child2","Amran","123456","ACTIVE","Evening",1,29,"2017-11-09 19:45:00"]]}
好的,这是我从服务器收到的json格式
现在我想将其解码为我的结构,但仍然没有运气。
struct ChildrenTable: Decodable { var values: [[String]]?}
我在URLSession上的调用方方法如下所示
URLSession.shared.dataTask(with: request) { (data, response, err) in guard let data = data else { return } let dataAsString = String(data: data, encoding: .utf8) print(dataAsString) do { let children = try JSONDecoder().decode(ChildrenTable.self, from: data) print (children) } catch let jsonErr { print ("Error serializing json: ", jsonErr) } }.resume()
我得到的错误是
Error serializing json: typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [Vito_Parent.ChildrenTable.(CodingKeys in _1B826CD7D9609504747BED0EC0B7D3B5).values, Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0)), Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0))], debugDescription: "Expected to decode String but found a number instead.", underlyingError: nil))
我知道数组中有一个整数,并且我只将String转换为值var values:[[String]]?
(此错误弹出窗口的原因),但是我根本不能在结构中使用任何多维数组或元组,因为它遵循Decodable协议。
我也无法将数据转换为字典,因为它将引发错误“预期对字典进行解码,但找到了数组”
有解决这个问题的想法吗?我尝试在数据上强制转换字符串类型,但仍然没有运气…
p / s:如果所有json格式都是字符串类型,那不会有问题,但是由于我从API调用它,因此我没有更改权限。
答案1
小编典典如您所说,您的json数组是多类型的,但您尝试将所有内容解码为String
。默认的一致性String
,以Decodable
不允许。我想到的唯一解决方案是引入新类型。
struct IntegerOrString: Decodable { var value: Any init(from decoder: Decoder) throws { if let int = try? Int(from: decoder) { value = int return } value = try String(from: decoder) }}struct ChildrenTable: Decodable { var values: [[IntegerOrString]]?}
在线运行
2.9 多维数组的创建和遍历 [Swift原创教程]
原文:http://www.coolketang.com/staticCoding/5a992425128fe1189bdbc7c4.html
1. 本节课将以二维数组为例,演示多维数组的定义和遍历。
2. 首先创建第一个数组,该数组拥有三个整型元素。
3. 接着创建第二个数组,该数组拥有四个整型元素。
4. 然后创建一个二维数组,并直接给它赋值。它由两个数组元素组成。
5. 定义第二个二维数组,并指定数组的类型为整型。
6. 通过附加方法,将两个子数组,依次添加到二维数组中。
7. 通过for-in循环,可以对多维数组进行遍历。
8. 通过第二个循环语句,对子数组进行遍历,并输出子数组中的所有元素。接着点击右侧的显示结果图标,显示输出的结果列表。
9. 接着在列表中点击鼠标右键,打开选项菜单。
10. 选择菜单中的查看历史值选项。
11. 此时在列表中显示了所有输出的结果,点击垂直滚动条,查看底部隐藏的结果,并结束本节课程。
12.
ios – Swift:从接口类型数组转换为对象数组崩溃
interface SomeInterface{}
和一个符合该接口的类
class SomeClass : NSObject,SomeInterface{}
现在,我创建一个SomeInterface对象数组
var myInterfaceObjects : SomeInterface[] = SomeInterface[]()
然后我想将此数组转换为SomeClass对象数组
var someClassObjects : SomeClass[] = myInterfaceObjects as SomeClass[] //CRASH!
我如何在没有崩溃的情况下垂头丧气?
Fatal error: can't reinterpretCast values of different sizes (lldb) bt * thread #1: tid = 0x935ef,0x001986b8 libswift_stdlib_core.dylib`Swift.reinterpretCast <A,B>(A) -> B + 220,queue = 'com.apple.main-thread',stop reason = EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT,subcode=0xe7ffdefe) * frame #0: 0x001986b8 libswift_stdlib_core.dylib`Swift.reinterpretCast <A,B>(A) -> B + 220 frame #1: 0x001bebdc libswift_stdlib_core.dylib`Swift.ContiguousArrayBuffer.storesOnlyElementsOfType <A>(Swift.ContiguousArrayBuffer<A>)<B>(B.Type) -> Swift.Bool + 912 frame #2: 0x001bde08 libswift_stdlib_core.dylib`Swift._arrayCheckedDownCast <A,B>(Swift.Array<A>) -> Swift.Optional<Swift.Array<B>> + 292 frame #3: 0x00094c84 MyApp`MyApp.MyClass.(data=SomeInterface[]! at 0x27db0870,response=Foundation.NSHTTPURLResponse! at 0x27db086c,error=None,self=<unavailable>) -> (Swift.Bool) -> ()).(closure #1) + 428 at MyClass.swift:81
解决方法
现在,您可以尝试通过单独转换对象来解决它:
var someClassObjects : [SomeClass] = myInterfaceObjects.map { $0 as SomeClass }
编辑:更新到最新的swift语法.另外值得一提的是这个bug可能已在beta 3或beta 4中得到解决 – 我还没有检查过
ios – Swift:使用Alamofire和SwiftyJSON处理JSON
我使用Alamofire和SwiftyJSON,我的JSON数据看起来像这样:
{ "528" : { "name" : "Name 1","id" : "528","product_id" : null,"visible" : "0","level" : "2" },"29" : { "name" : "Name 2","id" : "29","visible" : "1","level" : "1" },"173" : { "name" : "Name 3","id" : "173","143" : { "name" : "Name 4","id" : "143",
…使用此代码:
Alamofire.request(.GET,dataURL,parameters: nil,encoding: .JSON) .responseJSON { (request,response,jsonData,error) in let json = JSON(jsonData!) println(json) }
…所以JSON一切都应该没问题
>我如何访问该数据?我的意思是我如何获得名称,ID,product_ids等
>我如何将该数据(名称)放入我的TableViewController?
解决方法
>创建一个名为APIProtocol的协议.
>使用GET方法设置API类,该方法接受APIProtocol类型的委托.
>设置TableViewController以实现APIProtocol.
>从TableViewController调用API.get()
码
// Step 1 protocol APIProtocol { func didReceiveResult(results: JSON) } // Step 2 func get(path: String,parameters: [String: AnyObject]? = nil,delegate: APIProtocol? = nil){ let url = "\(self.hostname)\(path)" NSLog("Preparing for GET request to: \(url)") Alamofire.request(.GET,url,parameters: parameters) .responseJSON { (req,res,json,error) in if(error != nil) { NSLog("GET Error: \(error)") println(res) } else { var json = JSON(json!) NSLog("GET Result: \(json)") // Call delegate if it was passed into the call if(delegate != nil) { delegate!.didReceiveResult(json) } } } } // Step 3 class ActivityViewController: UITableViewController,APIProtocol { var activityModelList: NSMutableArray = [] // This is the array that my tableView is using. ... func didReceiveResult(result: JSON) { var activities: NSMutableArray = [] NSLog("Activity.didReceiveResult: \(result)") for (index: String,activity: JSON) in result { var activityModel = ActivityModel( id: activity["id"].intValue,message: activity["message"].stringValue ) activities.addobject(activityModel) } // Set our array of new models activityModelList = activities // Make sure we are on the main thread,and update the UI. dispatch_sync(dispatch_get_main_queue(),{ self.refreshControl!.endRefreshing() self.tableView.reloadData() }) } } // Step 4 override func viewDidLoad() { MyAPI.get("/activities",delegate: self) }
json – Swift 4可解码,带有未知的动态键
{"DynamicKey":6410,"Meta":{"name":"","page":""}}
DynamicKey在编译时是未知的.我正在尝试找到如何的引用
使用decodable解析此结构.
public struct MyStruct: Decodable { public let unkNown: Double public let Meta: [String: String] private enum CodingKeys: String,CodingKey { case Meta = "Meta" } }
有任何想法吗?
解决方法
// Arbitrary key private struct Key: CodingKey,Hashable,customstringconvertible { static let Meta = Key(stringValue: "Meta")! var description: String { return stringValue } var hashValue: Int { return stringValue.hash } static func ==(lhs: Key,rhs: Key) -> Bool { return lhs.stringValue == rhs.stringValue } let stringValue: String init(_ string: String) { self.stringValue = string } init?(stringValue: String) { self.init(stringValue) } var intValue: Int? { return nil } init?(intValue: Int) { return nil } }
这是一个非常通用的工具(期望静态let元),可用于各种通用密钥问题.
有了它,你可以找到不是.Meta的第一个键,并将其用作动态键.
public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: Key.self) Meta = try container.decode([String: String].self,forKey: .Meta) guard let dynamicKey = container.allKeys.first(where: { $0 != .Meta }) else { throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [],debugDescription: "Could not find dynamic key")) } unkNown = try container.decode(Double.self,forKey: dynamicKey) }
一起作为一个游乐场:
import Foundation let json = Data(""" {"DynamicKey":6410,"page":""}} """.utf8) public struct MyStruct: Decodable { public let unkNown: Double public let Meta: [String: String] // Arbitrary key private struct Key: CodingKey,customstringconvertible { static let Meta = Key(stringValue: "Meta")! var description: String { return stringValue } var hashValue: Int { return stringValue.hash } static func ==(lhs: Key,rhs: Key) -> Bool { return lhs.stringValue == rhs.stringValue } let stringValue: String init(_ string: String) { self.stringValue = string } init?(stringValue: String) { self.init(stringValue) } var intValue: Int? { return nil } init?(intValue: Int) { return nil } } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: Key.self) Meta = try container.decode([String: String].self,forKey: .Meta) guard let dynamicKey = container.allKeys.first(where: { $0 != .Meta }) else { throw DecodingError.dataCorrupted(.init(codingPath: [],debugDescription: "Could not find dynamic key")) } unkNown = try container.decode(Double.self,forKey: dynamicKey) } } let myStruct = try! JSONDecoder().decode(MyStruct.self,from: json) myStruct.unkNown myStruct.Meta
这项技术可以扩展到decode arbitrary JSON.有时它更容易做到,然后拉出你想要的部分,然后解码每一件.例如,使用上面的JSON要点,您可以这样实现MyStruct:
public struct MyStruct: Decodable { public let unkNown: Double public let Meta: [String: String] public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() let json = try container.decode(JSON.self) guard let Meta = json["Meta"]?.dictionaryValue as? [String: String] else { throw DecodingError.dataCorrupted(.init(codingPath: [],debugDescription: "Could not find Meta key")) } self.Meta = Meta guard let (_,unkNownjsON) = json.objectValue?.first(where: { (key,_) in key != "Meta" }),let unkNown = unkNownjsON.doubleValue else { throw DecodingError.dataCorrupted(.init(codingPath: [],debugDescription: "Could not find dynamic key")) } self.unkNown = unkNown } }
我们今天的关于具有多维和多类型数组的Swift 4 JSON可解码和json多维数组 格式的分享已经告一段落,感谢您的关注,如果您想了解更多关于2.9 多维数组的创建和遍历 [Swift原创教程]、ios – Swift:从接口类型数组转换为对象数组崩溃、ios – Swift:使用Alamofire和SwiftyJSON处理JSON、json – Swift 4可解码,带有未知的动态键的相关信息,请在本站查询。
本文标签: