【问题标题】:How to append struct into Array? Swift4如何将结构附加到数组中?斯威夫特4
【发布时间】:2018-10-10 10:41:29
【问题描述】:

功能

import Foundation

struct Foods {
    var fid: Int
    var fname: String
    var hits: Int?
    var addr: String?
}

class Food {

    func getFoodsById(_ fid: Int) -> [Foods]? {
        var foods: Array<Foods>?
        let URL_GET_TEAMS:String = "http://jsm0803.iptime.org:81/html/sufoo/getFoodById.php"
        let requestURL = URL(string: URL_GET_TEAMS)

        let request = NSMutableURLRequest(url: requestURL!)

        request.httpMethod = "POST"
        //request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        let postParameters = "Fid=" + String(fid)
           // "name="+teamName!+"&member="+memberCount!;

        request.httpBody = postParameters.data(using: String.Encoding.utf8)


        let task = URLSession.shared.dataTask(with: request as URLRequest){data, response, error in

            if error != nil{
                print("error is \(error)")
                return;
            }
            let dataString = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) // 테스트용
            //print(dataString!)


            do{
                var itemJSON: Dictionary<String, Any>!
                itemJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? Dictionary


                let items:Array<Dictionary<String, Any>> = itemJSON["Food"] as! Array

                for i in 0 ..< items.count{
                    var food: Foods
                    let item = items[i]

                    let fid:Int = item["Fid"] as! Int
                    let fname: String = item["Fname"] as! String
                    let hits: Int? = item["Hits"] as? Int
                    let delegate_image:String? = item["Delegate_Image"]as? String

                    food = Foods(fid: fid, fname: fname, hits: hits, addr: delegate_image)

                    foods?.append(food)



                    print("fid ->", food.fid)
                    print("fname ->", food.fname)
                    if let f = food.hits {
                        print("hits ->", f)
                    }
                    else{
                        print("hits ->", food.hits as Any)
                    }
                    if let f = food.addr {
                        print("delegate_image -> ", f)
                    }
                    else {
                        print("delegate_image -> ", food.addr as Any)
                    }

                    print("==============")
                    print("")

                    print ("fid ==== ", foods?.first?.fid)
                    print ("fid ==== ", foods?.last?.fid)

                }
            }catch {
                print(error)
            }
        }
        task.resume()

        if let result = foods{
            for r in result{
                print ("r.fname")
                print (r.fname)
            }
        }
        print ("000000")
        return foods
    }

}

如果我在 Xcode 中运行此代码,我会得到以下结果:

000000

fid -> 140

fname -> 밀흑밀

命中 -> 无

delegate_image -> ./pic_data/2309/20180423201954alj

==============

fid ==== 无
fid ==== 无

我想返回 [var foods: Array?] 值。 但是,虽然我创建了 Foods 结构的一些值并使用 Array 的 append 函数将 Foods 值添加到 Array 中,但它不起作用。 Array中没有值,只有nil。(fid ==== nil) 因此,返回该数组是没有用的。

我怎样才能得到正确的结果?

我需要得到如下值:

fid ==== 140
fid ==== 140

请帮我解决这个问题。 我想我用错了 Optional。

【问题讨论】:

    标签: ios arrays iphone swift optional


    【解决方案1】:

    最好制作一个模型类来存储数据。例如:

    class Food {
      var fid: Int
      var fname: String
      var hits: Int?
      var addr: String?
    }
    

    然后在得到结果后做这样的事情:

    var foodArray = [Foods]()
    for item in items {
       let food = Food()
       guard let food.fid = item["Fid"] as? Int else {return}
       foodArray.append(food)
    }
    print(foodArray)
    

    并由 Francesco Deliro 建议,在您的 for 循环完成时使用完成处理程序返回值。在您的情况下,return 语句在 for 循环结束之前被调用。

    Also don't do force unwrapping, try to use if let/ guard let .
    

    【讨论】:

    • 不要让一个类无缘无故地从NSObject继承,Swift不是Objective-C,类不需要从基类继承。此外,您的 struct 除非您明确需要引用类型行为/继承并使变量不可变,除非它们需要可变。
    【解决方案2】:

    您需要更改您的函数实现添加一个完成处理程序,因为您的 return 在 for 循环结束之前被调用:

    func getFoodsById(_ fid: Int, completion: (([Foods]?, Error?) -> Void)?) {
    
        //your precedent code
        //then when you make the request call the completion
    
        let task = URLSession.shared.dataTask(with: request as URLRequest){data, response, error in
    
            guard error == nil else {
                completion?(nil, error)
                return
            }
            let dataString = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) // 테스트용
            //print(dataString!)
    
    
            do{
                var itemJSON: Dictionary<String, Any>!
                itemJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? Dictionary
    
    
                let items:Array<Dictionary<String, Any>> = itemJSON["Food"] as! Array
    
                for i in 0 ..< items.count{
                    var food: Foods
                    let item = items[i]
    
                    let fid:Int = item["Fid"] as! Int
                    let fname: String = item["Fname"] as! String
                    let hits: Int? = item["Hits"] as? Int
                    let delegate_image:String? = item["Delegate_Image"]as? String
    
                    food = Foods(fid: fid, fname: fname, hits: hits, addr: delegate_image)
    
                    foods?.append(food)
    
    
    
                    print("fid ->", food.fid)
                    print("fname ->", food.fname)
                    if let f = food.hits {
                        print("hits ->", f)
                    }
                    else{
                        print("hits ->", food.hits as Any)
                    }
                    if let f = food.addr {
                        print("delegate_image -> ", f)
                    }
                    else {
                        print("delegate_image -> ", food.addr as Any)
                    }
    
                    print("==============")
                    print("")
    
                    print ("fid ==== ", foods?.first?.fid)
                    print ("fid ==== ", foods?.last?.fid)
    
                }
                completion?(foods, nil)
            }catch {
                print(error)
                completion?(nil, error)
            }
        }
        task.resume()
    }
    

    你可以这样使用它:

    //where you have to make the call
    self.getFoodsById(yourId) { (foodsArray, error) in
        //here you can manage your foods array
    }
    

    【讨论】:

    • 谢谢!但是我从来没有使用过Completion Handler,所以我不知道如何调用它。你能给我举个例子吗?
    • @SoonmyunJang 我已经编辑了我的答案,以展示如何使用完成处理程序;)
    【解决方案3】:

    主要问题是您没有启动您的食物数组。

    //func getFoodsById(_ fid: Int) -> [Foods]? {
    func getFoodsById(_ fid: Int) -> [Foods] {
        //var foods: Array<Foods>?
        var foods = [Foods]() // or  var foods: [Foods] = []
    

    您可以在此处启动您的数组,如果 ID 没有食物,则返回空列表。

    然后将你的 Foods 结构重命名为 Food 和 Food 类,比如 FoodOperations。这会更有意义。

    阅读this 获取快速指南。

    struct Food {
        ...
    }
    class FoodOperations {
        ...
    }
    
    if let error = error {
       print("error is \(error)")
       return;
    }
    
    print ("fid ==== ", foods.first?.fid ?? 0)
    

    【讨论】:

    • 对……我忘了。谢谢,我改了,但是我的代码还是有'return'的问题。
    【解决方案4】:

    声明结构

    struct AlertModel { var alert:String var title:String }
    

    创建变量

    var alertData = AlertModel
    

    追加数据

    let alert = AlertModel(alert: "Waring", title: "Over Load") alertData.append(alert)
    print(alertData)
    

    【讨论】:

      猜你喜欢
      • 2019-03-23
      • 2017-07-22
      • 2017-03-24
      • 2018-01-04
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多