如何将struct附加到Array中? Swift4

时间:2018-04-30 10:37:13

标签: ios arrays iphone swift optional

功能

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 - &gt; 140

     

fname - &gt; 밀흑밀

     

点击 - &gt;没有

     

delegate_image - &gt; ./pic_data/2309/20180423201954alj

     

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

     

fid ====无   fid ==== nil

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

如何才能获得正确的结果?

我需要获得如下的值:

  

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

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

4 个答案:

答案 0 :(得分: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语句。

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

答案 1 :(得分:0)

您需要更改函数实现添加完成处理程序,因为在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
}

答案 2 :(得分:0)

主要问题是你没有开始你的食物阵列。

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

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

使用像FoodOperations这样的食物和食物类重命名你的Foods结构。这会更有意义。

阅读this以获取快速指南。

struct Food {
    ...
}
class FoodOperations {
    ...
}

if let error = error {
   print("error is \(error)")
   return;
}

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

答案 3 :(得分:0)

声明结构

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

创建变量

var alertData = AlertModel

追加数据

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