0

This is a rough example (the actual use-case I am working on has to do with the internals of PHImageManager's requestImageForAsset: function), but I'm looking for a pattern that allows you to re-run a function based on the results in the completion block.

Playground code:

private func subtractTen (value: Int, completion: (success: Bool, newVal: Int, [NSObject: AnyObject]?) -> Void) -> Int {
  // This is private to represent a black box.
  // In my personal use-case, it's actually a Foundation method
  completion(success: (value - 10 >= 0), newVal: value - 10, nil)

  return value - 10
}

func alwaysPositive (value: Int) -> Int {
  var foo: Int

  foo = subtractTen(value) { success, newVal, _ in

    if success {
      print ("yay")
    } else {
      // I need subtractTen re-run with a new input: newVal
      // and I need the resulting value in the calling function
      // (in this case, "foo")
      print ("re-run subtractTen with newVal, and return the value to the parent function")
    }

    return
  }

  return foo
}

alwaysPositive(10)

You can run alwaysPositive with values such as 1, 2, 9, 10, 11, etc. to see when the "re-run" message gets displayed.

Is there a common Swift pattern for what I'm trying to do?

Jeffrey Berthiaume
  • 4,054
  • 3
  • 35
  • 45

1 Answers1

1

Look at this code, maybe it will help what you are looking for:

override func viewWillAppear(animated: Bool) {
    rerunThis(0, callback: { (number_returned: Int, returned: Bool) in
        println("returned: \(number_returned), \(returned)");

        self.rerunThis(number_returned, callback: { (new_number_returned: Int, returned: Bool) in
            println("new returned: \(new_number_returned), \(returned)");
        });
    });
}

func rerunThis(last_number: Int, callback: ((Int, Bool)->Void)) {
    let new_value: Int = last_number+1;
    var return_this: Bool = false;
    if (new_value <= 1){
        return_this = true;
    }
    callback(new_value, return_this);
}
Ghulam Ali
  • 1,935
  • 14
  • 15
  • What's with the snake case? – GetSwifty May 09 '16 at 20:54
  • I updated the answer to be more readable for old style programmers ;) – Ghulam Ali May 09 '16 at 20:58
  • Yes, that re-runs the function -- but that example doesn't also return a value. If it did, re-running the function wouldn't update the value properly. – Jeffrey Berthiaume May 09 '16 at 21:07
  • Also, callback is always nil and is never used. – Jeffrey Berthiaume May 09 '16 at 21:16
  • I am having difficulty understanding your question. But I updated the answer that will rerun the function based on result in callback. Maybe it will help. – Ghulam Ali May 09 '16 at 21:27
  • Have func rerunThis(last_number: Int, callback: ((Int)->Void)) -> Bool, where the return value is true if new_value is <= 1, and false otherwise. Then you need to let success = rerunThis... in the viewDidLoad. – Jeffrey Berthiaume May 09 '16 at 21:31
  • Using return with callback is not necessary as we can use the callback function to return the values otherwise we cannot get the returned value of function within the closure. So to get the value within the closure we need the callback values. I updated the answer that will return true for first callback and false for second. – Ghulam Ali May 09 '16 at 21:53