1

I am trying to change a global variable from within an alamofire variable but am having issues doing it. Here is my code:

var projects = [[String]]()
var xmlToParse = String()
var postTitle = String()
var postLink = String()

override func viewDidLoad() {
    super.viewDidLoad()

    httpRequest("https://www.hello.com/feed") { response in
        self.xmlToParse = response as String
        let xml = SWXMLHash.parse(self.xmlToParse)

        for elem in xml["rss"]["channel"]["item"].all {
            self.postTitle = elem["title"].element!.text
            self.postLink = elem["link"].element!.text                
            self.projects.append([self.postTitle, self.postLink])
        }
    }
    print(self.projects)
}

When I print self.projects here, i get an empty array, however when I print it inside the httpRequest function I get the proper data. Am I not setting the global variable projects within the for loop? How can I get the value outside of that function? I have tried everything I found on SO with no success. Any help is greatly appreciated.

Just for more info, here is my httpRequest function:

func httpRequest(_ section: String, completion: @escaping (String) -> Void) {
    Alamofire.request(section, method: .get).responseString { response in
        completion(response.result.value!)
    }
}
dan boy
  • 89
  • 8
  • 2
    it is because you are printing self.projects even before httpRequest function calls the completion handler. – koropok Oct 17 '17 at 00:56
  • Hmm.. So how can I get it so that projects array can be accessed in ViewDidLoad with the proper data in it, as well as in other functions? – dan boy Oct 17 '17 at 00:59
  • why not just place your logic within the completion handler? – koropok Oct 17 '17 at 01:01
  • I have tried that, but the array is still empty. Do you have an example? I must be doing it wrong somehow – dan boy Oct 17 '17 at 01:10
  • 1
    Learn the difference between async and sync. Search for @escaping functions. – J. Doe Oct 17 '17 at 01:15
  • Possible duplicate of [How to return value from Alamofire](https://stackoverflow.com/questions/27390656/how-to-return-value-from-alamofire) – Ssswift Oct 17 '17 at 01:26

1 Answers1

1

Assuming that xml["rss"]["channel"]["item"] is not nil...

override func viewDidLoad() {
    super.viewDidLoad()

    httpRequest("https://www.hello.com/feed") { response in
        self.xmlToParse = response as String
        let xml = SWXMLHash.parse(self.xmlToParse)

        for elem in xml["rss"]["channel"]["item"].all {
            self.postTitle = elem["title"].element!.text
            self.postLink = elem["link"].element!.text                
            self.projects.append([self.postTitle, self.postLink])
        }

        self.setup()
    }
}

func setup() {
    // Your logic here
}
koropok
  • 1,393
  • 13
  • 19
  • Thanks for this. I am confused what goes in setup though. the original func httpRequest? – dan boy Oct 17 '17 at 01:15
  • Also, the next thing I'm doing will be error handling for nil :) – dan boy Oct 17 '17 at 01:19
  • you can put the codes on what you plan to do with self.projects within setup. By doing so, you can ensure that self.projects variable is already assigned with some value. – koropok Oct 17 '17 at 01:25
  • the problem is i'm trying to populate a tableview cell with items from the array so i can't call the tableview function in setup – dan boy Oct 17 '17 at 01:33
  • why not? if you have set your tableview delegate and datasource correctly you can simply do a tableview.reloadData() – koropok Oct 17 '17 at 01:36
  • That was it! I completely slipped my mind about reloadData even though I used it elsewhere, thanks so much!!! – dan boy Oct 17 '17 at 01:38