1

I have a list of a custom object that I want to change it's value by passing it to a function: My code below:

func UpdateButtonPressed(_Url : String,referenceArray: inout Array<Item>)
{

    var _itemList = [Item]()
    var result:String! = ""
    let url = URL(string:_Url)
    var request = URLRequest(url: url! as URL)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let session = URLSession.shared
    let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
        guard data != nil else {
            print("no data found: \(error)")
            return }
        do {
            let temp = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            result = String(describing: temp!)
            DispatchQueue.main.async {
               referenceArray.append(contentsOf:  self.UpdateItem(result:result))
            }
        }
    })
    task.resume()
}

func UpdateItem(result:String)-> [Item]
{
    var _itemList = [Item]()
    _itemList = Item.ConvertJSONToItemList(result: result)
    return _itemList
}

and I call my function as below:

 var mostRecent = [Item]()
       UpdateButtonPressed(_Url:PublicVariables.GetMostRecent(), referenceArray: &mostRecent)

But it's not worked, How can I do that?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 2
    You see review https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function?s=4|61.1451 – rmaddy Mar 21 '18 at 15:30

2 Answers2

0

You can try completions

      func UpdateButtonPressed(_ Url : String , completion: @escaping (_ arr: [Item]) -> Void)       
      {

        var _itemList = [Item]()
        var result:String! = ""
        let url = URL(string:_Url)
        var request = URLRequest(url: url! as URL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        let session = URLSession.shared
        let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
            guard data != nil else {
                print("no data found: \(error)")
                return }
            do {
                let temp = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                result = String(describing: temp!)
                DispatchQueue.main.async {

                    completion(self.UpdateItem(result:result))

                }
            }
        })
        task.resume()

 }

call like this

    UpdateButtonPressed("") { (items) in

    }
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • When I use this with many list is retrive (fill) one list only, How can I resolve That? –  Mar 21 '18 at 18:34
0

The start of the problem is you are using an anti-pattern. You should strive for your functions to be first level functions ( input and output). You can fix this by using completion blocks, or something like a bright future, or rx swift. Anyway, you need to get rid of inout parameters.

take a look at this links:

https://thatthinginswift.com/completion-handlers/

https://github.com/ReactiveX/RxSwift

https://github.com/Thomvis/BrightFutures

Boris
  • 178
  • 1
  • 7