Reputation: 330
Function
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
}
}
If I run this code in Xcode, I get the result below:
000000
fid -> 140
fname -> 밀 흑밀
hits -> nil
delegate_image -> ./pic_data/2309/20180423201954alj
==============
fid ==== nil
fid ==== nil
I want to return [var foods: Array?] value. But although I made some values of Foods struct and used append function of Array in order to add Foods value into Array, it didn't works. There is no value in Array, only nil.(fid ==== nil) Thus, it is useless to return that Array.
How can I get right results?
I need to get values like below:
fid ==== 140
fid ==== 140
Please help me to solve this problem. I think I used Optional wrongly.
Upvotes: 0
Views: 2759
Reputation: 37
Declare Struct
struct AlertModel { var alert:String var title:String }
Create Variable
var alertData = AlertModel
Append data
let alert = AlertModel(alert: "Waring", title: "Over Load") alertData.append(alert)
print(alertData)
Upvotes: 0
Reputation: 3939
You need to change your function implementation adding a completion handler, because your return is called before the for loop is ended:
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()
}
And you can use it in this way:
//where you have to make the call
self.getFoodsById(yourId) { (foodsArray, error) in
//here you can manage your foods array
}
Upvotes: 0
Reputation: 4891
Better make a model class to store data. For example:
class Food {
var fid: Int
var fname: String
var hits: Int?
var addr: String?
}
Then after getting result do something like this :
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)
And suggested by Francesco Deliro, use completion handler to return values when your for loop is done. In your case return statement is getting called before for loop ends.
Also don't do force unwrapping, try to use if let/ guard let .
Upvotes: 1
Reputation: 6715
Main problem is you did not initiate your foods array.
//func getFoodsById(_ fid: Int) -> [Foods]? {
func getFoodsById(_ fid: Int) -> [Foods] {
//var foods: Array<Foods>?
var foods = [Foods]() // or var foods: [Foods] = []
You can initiate your array here and return empty list as a result if there is no food for the ID.
And rename your Foods struct with Food and Food class with something like FoodOperations. This would make more sense.
Read this for swift guides.
struct Food {
...
}
class FoodOperations {
...
}
if let error = error {
print("error is \(error)")
return;
}
print ("fid ==== ", foods.first?.fid ?? 0)
Upvotes: 1