GVKun编程网logo

具有多维和多类型数组的Swift 4 JSON可解码(json多维数组 格式)

15

如果您想了解具有多维和多类型数组的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多维数组 格式)

具有多维和多类型数组的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原创教程]

2.9 多维数组的创建和遍历 [Swift原创教程]

原文:http://www.coolketang.com/staticCoding/5a992425128fe1189bdbc7c4.html

1. 本节课将以二维数组为例,演示多维数组的定义和遍历。



2. 首先创建第一个数组,该数组拥有三个整型元素。
3. 接着创建第二个数组,该数组拥有四个整型元素。
4. 然后创建一个二维数组,并直接给它赋值。它由两个数组元素组成。
5. 定义第二个二维数组,并指定数组的类型为整型。
6. 通过附加方法,将两个子数组,依次添加到二维数组中。
7. 通过for-in循环,可以对多维数组进行遍历。
8. 通过第二个循环语句,对子数组进行遍历,并输出子数组中的所有元素。接着点击右侧的显示结果图标,显示输出的结果列表。
9. 接着在列表中点击鼠标右键,打开选项菜单。
10. 选择菜单中的查看历史值选项。
11. 此时在列表中显示了所有输出的结果,点击垂直滚动条,查看底部隐藏的结果,并结束本节课程。
12.
本文整理自:《Swift4互动教程》,真正的 [手把手]教学模式,用最快的速度上手iOS开发和Swift语言,苹果商店App Store免费下载: https://itunes.apple.com/cn/app/id1320746678 ,或扫描本页底部的@R_301_6272@。课程配套素材下载地址: 资料下载

ios – Swift:从接口类型数组转换为对象数组崩溃

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

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?

解决方法

我在我的一个项目中使用了SwiftyJSON和Alamofire.这是我如何使用它.

>创建一个名为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可解码,带有未知的动态键

json – Swift 4可解码,带有未知的动态键

我有以下 JSON

{"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可解码,带有未知的动态键的相关信息,请在本站查询。

本文标签: