2017-04-12 8 views
0

私はfuncから返すことができるように、私のforループの値と等しい戻り値を設定したいと思います。それをどうやって行うのか考えていますか?戻り値forループの文字列 - Swift 3

static func getStones() -> Double { 
    let url = NSURL(string: "MYURL") 
    let request = NSMutableURLRequest(url: url as URL!) 
    var stonesNew = Double() 

    let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in 
     let responseString = try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary 
     let contacts = responseString["Sheet1"] as? [AnyObject] 

     for contact in contacts!{ 
      let stones = contact["stones"] as! Double 
      stonesNew = stones 
     } 

    } 
    task.resume() 
    return stonesNew 
} 
  • だから、私はダウンロードした「石」を「stonesNew」に設定したいと思いますが、それは常に石= 0
+0

トムuがstonesNewに石の値を設定することを意味しましたの? – Anuraj

+0

石の合計を返したいですか?常にゼロを返します。 – ChanWarde

+0

'task.resume()'はタスクを開始してから戻ります。だからそれが終わり、あなたが 'stoneNew'を返すとき、その仕事はまだ完了していません。このようにしなければならない場合は、結果がサーバーから返されるのを待つためにセマフォーを使用する必要があります。 より良いアプローチは、結果が返されたときに呼び出すためにこの関数にハンドラを渡すことです。 –

答えて

1

dataTaskは、非同期タスクですが返されます。したがって、この関数はdataTaskが完了する直前に常にstonesNewを返します。

static func getStones(completion: @escaping (Double) -> Void) { 
    let url = NSURL(string: "MYURL") 
    let request = NSMutableURLRequest(url: url as URL!) 
    var stonesNew = Double() 
    let task = URLSession.shared.dataTask(with: request as URLRequest) {data,response,error in 

     let responseString = try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary 
     let contacts = responseString["Sheet1"] as? [AnyObject] 

     for contact in contacts!{ 

      let stones = contact["stones"] as! Double 
      stonesNew = stones 
     } 

     completion(stonesNew) 
    } 
    task.resume() 
} 

そして、このようにそれを使用します:dataTaskは非同期であるため、

MyClass.getStones(completion: { (stones) in  
    print(stones) 
}) 
+0

私が間違っていたら私を訂正してください。しかし、今度は私の次のコーディングのために再利用可能な石の変数を作成する方法がありますか? たとえば、ダウンロードした二重石= 10.0の場合 この値を次のコーディングの通常の定数として使用したいと思います。 let stonesConstant = myClass.getStones(...たとえば配列の場合:let arr = [stonesConstant] – Tom

0

あなたがすることはできませんので、非同期タスクのためのソリューションは、このように、completionHanlderです。あなたは、次の遊び場を参照し、後の段階で変数stonesNewの値を受け入れるようにコードをリファクタリングする必要が

import UIKit 


let textField = UITextField() 
// This is probably something like your code now... a function is doing something with the value of newStones 
func buttonPressed() { 
    textField.text = "\(getStones())" 
} 
// And this is your current getStones function 
func getStones() -> Double { 
    // the code you have now 
    return 0 
} 

// Let's see how we can do things with callbacks 
func buttonPressedV2() { 
    newGetStnes { (newStones) in 
     textField.text = "\(newStones)" 
    } 
} 

func newGetStnes(callback: (Double) ->()) { 
    let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in 
     // calculate newStones the way you were doing.. 
     // The following will call back your function, giving the result 
     callback(newStones) 
    } 
} 
関連する問題