Do I need to wrap my Alamofire calls inside dispatch_async?
Alamofire is designed to be asynchronous. On another note, if the method has as callback, most likely it is asynchronous.
So, yes you can leave out the dispatch_async calls.
How to make sure that an Alamofire request runs?
We need to do two things.
- Execute the request in the background.
- Block the main thread until the request is done, i.e. the completion handler ran.
My original code does neither.
The first item is achieved by using .response(queue: DispatchQueue(label: "some-name"))
(or one of its variants).
Waiting can be done in several ways.
- Using a flag and active waiting, as shown here (won't scale to more than one request).
- Use active waiting with countdown latch as shown here (works for multiple requests).
- Use
DispatchSemaphore
as seen e.g. here.
And probably many more.
iOS - Asynchronous requests and UI interactions
Alamofire networks asynchronously. No worries there. The problem, though, is probably here:
let url = NSURL(string: image["unescapedUrl"] as! String)!
if let data = NSData(contentsOfURL: url) {
If, as I suspect, that URL is a remote URL, then you are now repeatedly networking synchronously. NSData(contentsOfURL:)
is not appropriate for fetching stuff across a network on the main thread. If you're going to reach out for more data on the network, use proper networking code - perhaps even using Alamofire some more...
AFNetworking 2 + SwiftyJSON
First of all, you don't need to dispatch to the main queue. AFNetworking already calls these blocks on the main thread.
The initializer you're using is expecting data, not a JSON object.
You're currently using this initializer, which expects an NSData
:
let json = JSON(data: dataFromNetworking)
Instead, you should be using this initializer:
let json = JSON(jsonObject)
SwiftyJSON will work fine if you pass responseObject
here.
One other note: this code doesn't belong in the completion blocks. In AFNetworking's design, you should be creating a response serializer that handles the server's response. I recommend looking at the source for AFJSONResponseSerializer
and porting that over to use SwiftyJSON.
How to perform segue after information from protocol is recieved
The other responders have hinted about this, but haven't stated it explicitly, so here goes.
Do not tie a segue directly to the button. Instead, control-drag from the source view controller SCENE to the destination scene to create a segue at the view controller level. Give the segue a unique identifier.
Then, in your button IBAction code, do the async network download. You may want to display a "loading, please wait" message or something while the download is taking place. Most async network calls take a completion block. In that completion block, wrap a call to performSegueWithIdentifier in a call to dispatch_async(dispatch_get_main_queue()
so the segue gets invoked on the main thread. (@SantaClaus's answer shows the syntax for that.)
So your button IBAction code might look like this:
- (IBAction) buttonAction: (UIButton *) sender;
{
//Display a "please wait"message to the user if desired
doAsyncCallTakingBlock( completion: ^(NSData *data)
{
//parse the data, (or whatever)
dispatch_async(dispatch_get_main_queue(), ^
{
//This call uses the button as the sender. That might be appropriate,
//or not.
[self performSegueWithIdentifier:@"jumpToOtherViewController"
sender: sender];
});
}
}
With this approach the segue doesn't get called until the async method (Which I called doAsyncCallTakingBlock
in my example code) has finished it's work. You might call an Alamofire request method, use an NSURLSession, or any other async method that takes a completion block.
Related Topics
How to Determine If a Business Is Open Given the Hours of Operation (Swift-Ios)
Display UI (Storyboard Possibly) with Broadcast UI Extension
Gmsmarker Icon in the Top Left Corner of the View (Ios)
Resize Inputaccessoryview Dynamically in iOS 8
Swiftui - Optional Timer, Reset and Recreate
Start/Stop Image View Rotation Animations
Swift Universal Framework Depending on Pod
How to Fill a Circle Color by Percentage Value
Convenience Initialization of Uinavigationcontroller Subclass Makes Subclass Constant Init Twice
My Uiviews Muck-Up When I Combine Uipangesturerecognizer and Autolayout
Where to Find a Clear Explanation About Swift Alert (Uialertcontroller)
How to Create a Pfquerytableviewcontroller with Parse in Swift
Show Two Different Custom Cells in Same Uitableview - Swift Firebase
How to Convert Data Dictionary into an Array Swift
Swiftui Transition from Modal Sheet to Regular View with Navigation Link