0

I am using AWS to host images for my iOS app. Right now I am trying to list all the objects in an S3 bucket.

Here is my code:

var description = ""
AWSS3.registerS3WithConfiguration(serviceConfig2, forKey: "s3")
AWSS3.S3ForKey("s3").listObjects(objectList).continueWithBlock { (task: AWSTask!) -> AnyObject! in
    if task.error != nil {
        println(task.error)
    }
    if task.result != nil {
        description = task.result!.description
        println(description)
    }
    return nil
}

println(description == "")

The output is true followed by the correct contents of task.result!.description. In other words, the println outside of the continueWithBlock is printing first and description has not been updated at that time.

How am I supposed to do things with description outside of the continueWithBlock?

Infamous911
  • 1,441
  • 2
  • 26
  • 41

2 Answers2

2

You can assign a value that you need to another variable inside the scope of your class or function, then you can call didSet on the variable and carry out another function if you need to, like this:

var someVariableInScopeOfWhereItsNeeded = "abc" {

    didSet {

        self.maybeSomeOtherFunctionNow

    }
}
Fred Faust
  • 6,696
  • 4
  • 32
  • 55
  • This doesn't work. When the `description` variable is set, the didSet method is not called, but if I put a `println(description)` after the variable initialization, then it does correctly do the `println` – Infamous911 Aug 14 '15 at 00:14
  • It depends on where you have the variable defined, for instance, if you have the variable defined outside of the scope of the function that begins the asynch task then it will get called. If you're defining it inside of a function that finishes before the variable is set it will never be called. Short answer, make description an instance variable. Also, see @Duncan C's answer and link – Fred Faust Aug 14 '15 at 00:16
  • Alright yeah I got it to work now, thanks. The question is, I have a bunch of code after this continueWithBlock, do I just have to put it all in the variable's didSet method? (The stuff after he continueWithBlock relies partly on the results of the continueWithBlock) – Infamous911 Aug 14 '15 at 00:32
  • You could create a variable of the type that's being returned in the block, then when it's set by the block send it all to another function or do something with it inside the didSet – Fred Faust Aug 14 '15 at 00:45
  • I made it so that another function is called in the didSet. In this function I change the text of a label. The label does not change when the function is called from the didSet block, but it does change if I call the function normally, outside of the didSet block. Any thoughts on this? – Infamous911 Aug 14 '15 at 01:14
  • I wound ensure the function is being called in a timely fashion, you can debug that with print statements, if it is then maybe try dispatching UI updates to the main thread – Fred Faust Aug 14 '15 at 01:16
  • What do you mean dispatch to the main thread? When I put `self.testLabel.text = "hello"` in the didSet method, it doesn't do anything, even though the didSet method is being called. When I put `self.testLabel.text = "hello"` outside of didSet, in viewDidLoad(), it works. – Infamous911 Aug 14 '15 at 01:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86940/discussion-between-thefredelement-and-infamous911). – Fred Faust Aug 14 '15 at 01:21
2

You asked:

How am I supposed to do things with description outside of the continueWithBlock

Short answer: You're not.

The whole point of an async method is that it continues immediately, before the time-consuming task has even begun processing. You put the code that depends on the results inside your block. See my answer on this thread for a detailed explanation, including an example project:

Why does Microsoft Azure (or Swift in general) fail to update a variable to return after a table query?

(Don't be fooled by the fact that it mentions MS Azure. It actually has nothing to do with Azure.)

@thefredelement 's solution of using a didSet method on the variable that gets set would work too.

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272