Tips:
This tutorial is based on Xcode 7.3, IOS 9.3, and Swift 2.2
Alamofire is a Swift-based HTTP network library for IOS and Mac OS. It provides an elegant interface on Apple's base Network library, simplifying many common network tasks.
Alamofire provides chained request and response methods, JSON parameters and response serialization and authorization, and so on. In this tutorial, you will use Alamofire to complete basic network tasks, including uploading files and using third-party library RESTful APIs to request data.
Note: For restful APIs You can refer to this blog RESTful API
The elegance of Alamofire is the fact that it was written entirely by Swift, without any objective-c code, nor inherited from Afnetworking.
You need to understand some of the basic concepts of HTTP and learn about Apple's network classes, such as NSURLSession
and NSURLConnection
.
While Alamofire obscures some of the implementation details, there are some background facts that are good if you need to address your Web request. You also need to use CocoaPods to install Alamofire into your tutorial project.
Entry
Download the initial project. After the download is completed, open the project run, you will find a button in the middle to select the picture, click the button will access the system's album, choose a picture, the background will be replaced by this picture. But now the project is an initial project, a lot of features are not completed, such as:
The final finish will look like this:
Imagga API
Imagga is a platform for image recognition as a service, providing developers and businesses with scalable image labeling APIs and image-dense cloud applications. You can download a sample program from their auto-tagging service.
You will need to create a free developer account on the Imagga website to complete this tutorial. Imagga requires an authorization header every time an HTTP request is made, so it must be registered to use their service. Go to Https://imagga.com/auth/signup/hacker to complete the registration. After registering successfully you will see an interface similar to the following:
The Authorization option is a token, which you will use later.
Attention:
Make sure you copy the entire token, because the token is very long.
You will use Imagga as the server for uploading images, labeling and setting colors for images. You can learn all the APIs in http://docs.imagga.com.
Install dependent packages
Create a file named in the Project Master directory Podfile
and open this file, which can be used in the following way:
touch Podfileopen Podfile
Then enter the following:
platform‘9.0‘‘PhotoTagger‘do ‘Alamofire‘‘~> 3.1.2‘end
Next, if you do not have CocoaPods installed on your PC, click on the link below to install the latest version of the CocoaPods installation process.
Close the project you just opened and open the terminal to the project catalog. Input pod install
, wait a few moments, and when you're done, you'll generate a PhotoTagger.xcworkspace
file named. Then compile and run your project and you'll see that nothing has changed, that's right, the next step is to add some HTTP requests from the RESTful server and return the JSON data.
What are the benefits of Alamofire?
Apple has offered NSURLSession
and other classes to download content, so why use Alamofire? Because Alamofire is based on nsurlsession, and it makes it easier for you to write code. You can get the data on the Internet without too much energy, and your code will be very concise and easy to read.
Here are some of the main functions in Alamofire:
.upload
: Upload a file in the form of a data stream, as part of a form, or as an entire file or data.
.download
: Download the file or resume the download after a pause.
.request
: Every HTTP request and file transfer is irrelevant.
The scope of these Alamofire functions is a module, not a class or struct. The bottom of the Alamofire are classes and structs, for example,, Manager
Request
and Response
, but you don't have to understand alamofire other structures when you start using them. Here is an example:
The following are used directly NSURLSession
:
With nsurlsessionpublic func fetchallrooms (completion: ([Remoteroom]?), Void) {Let URL = nsurl (string:"Http://localhost:5984/rooms/_all_docs?include_docs=true")! Let URLRequest = Nsmutableurlrequest (Url:url, CachePolicy:. Reloadignoringlocalandremotecachedata, timeOutInterval:10.0* +) Urlrequest.httpmethod ="GET"Urlrequest.addvalue ("Application/json", Forhttpheaderfield:"Accept") Let task = Urlsession.datataskwithrequest (urlrequest) {(data, response,Error), VoidinchGuardError==Nil Else{Print("error while fetching remote rooms: \ (Error)") Completion (Nil)return} guard Let JSON = try? Nsjsonserialization.jsonobjectwithdata (data!, Options: []) as? [String:anyobject]Else{Print("Nil data received from Fetchallrooms service") Completion (Nil)return} guard Let rows = json["Rows"] as?[[String:anyobject]]{Print("Malformed data received from Fetchallrooms service") Completion (Nil)return} var rooms = [Remoteroom] () forRoomdictinchRows {rooms.append (Remoteroom (jsondata:roomdict))} completion (Rooms)} task.resume ()}
Here's how to use Alamofire:
With Alamofirefunc fetchallrooms (completion: ([Remoteroom]?), Void) {alamofire.request (. GET,"Http://localhost:5984/rooms/_all_docs", Parameters: ["Include_docs":"true"], encoding:. URL). Validate (). Responsejson {(response), VoidinchGuard Response.result.isSuccessElse{Print("Error while fetching remote rooms: \ (response.result.error)") Completion (Nil)return} guard Let value = Response.result.value as? [String:anyobject], rows = value["Rows"] as?[[String:anyobject]] Else{Print("Malformed data received from Fetchallrooms service") Completion (Nil)return} var rooms = [Remoteroom] () forRoomdictinchRows {rooms.append (Remoteroom (jsondata:roomdict))} completion (rooms)}}
Uploading files
Open ViewController.swift
, add the following code to the bottom of the class:
// Networking callsextension ViewController { func uploadImage(image: UIImage, progress: (percent: Float) -> Void, completion: (tags: [String], colors: [PhotoColor]) -> Void) { guard let imageData = UIImageJPEGRepresentation(image, 0.5) else { print("Could not get JPEG representation of UIImage") return } }}
The function of the above code is to upload images to Imagga.
Next, in the imagePickerController(_:didFinishPickingMediaWithInfo:)
method, imageView.image = image
Add the following code later:
//1Takepicturebutton.hidden =trueProgressview.progress =0.0Progressview.hidden =falseActivityindicatorview.startanimating () uploadimage (image, Progress: {[unowned Self] percent in//2 Self. Progressview.setprogress (Percent, animated:true)}, Completion: {[unowned Self] tags, colors in//3 Self. Takepicturebutton.hidden =false Self. Progressview.hidden =true Self. Activityindicatorview.stopanimating () Self. tags = tags Self. colors = Colors//4 Self. Performseguewithidentifier ("Showresults", Sender: Self)})
All objects in the Alamofire are asynchronous, which means you can update the UI asynchronously:
- Hide the upload button while displaying the progress bar.
- When the file is uploaded, the progress closure is updated as a percentage, and the number of changes synchronized is displayed on the progress bar.
- When the upload file is complete, the completion closure is executed, and the state of the set control changes to its original state.
- Finally, Storyboard will display the results of successful (or unsuccessful) tea transfer on the screen, and the interface will not change based on the error.
Next, ViewController.swift
Add the following code in:
import Alamofire
The previous generation will allow you to use the code provided by the Alamofire module.
Below, return to uploadImage(_:progress:completion:)
and guard
add the following code after the judgment:
Alamofire.upload( .POST, "http://api.imagga.com/v1/content", headers: ["Authorization""Basic xxx"], in multipartFormData.appendBodyPart"imagefile", "image.jpg""image/jpeg") }, in })
Make sure to replace "Basic xxx" with your own token generated on the Imagga website.
Next, encodingCompletion
Add the following code in the closure:
switch encodingResult {case .Success(let upload, _, _): in dispatch_async(dispatch_get_main_queue()) { let percent = (Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)) progress(percent: percent) } } upload.validate() in }case .Failure(let encodingError): print(encodingError)}
This code calls the Alamofire upload feature to update the progress bar by calculating it.
Attention:
Alamofire does not guarantee that the calling process will be called back on the primary queue, so you must update the user interface by scheduling to the home row. There are some alamofire callbacks, for example responseJSON
, that will be called by default in the main queue. For example:
dispatch_async(queue ?? dispatch_get_main_queue()) { ... completionHandler(response)}
In order to change the default practice, you need to provide Alamofire with one dispatch_queue_t
.
Add the following code to upload.responseJSON
:
1.guard response.result.isSuccess Else {print ("Error while uploading file: \ (response.result.error)") Completion (tag S: [String](), Colors: [Photocolor]()) return}//2.guard Let Responsejson = Response.result.value as? [String:anyobject], uploadedfiles = responsejson["uploaded"] as? [Anyobject], firstfile = Uploadedfiles.first as? [String:anyobject], Firstfileid = firstfile["id"] as? String else {Print ("Invalid information received from service")Completion (Tags: [String] (), colors: [Photocolor] ())return}print ("Content uploaded with ID: \ (Firstfileid)")//3.completion (Tags: [String](), Colors: [Photocolor]())
The following is an explanation of each step:
1. Check that the response was successful, and if unsuccessful, output the error message and call completion
.
2. Check each part of the response, verify that the expected type is the actual type received, and if Firstfileid
is not parsed, output the error message and call completion
.
3. Call completion
to update the UI. You do not have any flags or colors to download, so simplify the case where the call data is empty.
Attention:
Each response has a result, including enumeration values and types. Use automatic authentication when it returns a valid HTTP code (the content type between 200-299 is considered acceptable).
You can .validate
manually perform the validation by adding the following code:
Alamofire.request(.GET"https://httpbin.org/get", parameters: ["foo""bar"]) .validate200..<300) .validate(contentType: ["application/json"]) .responsein // response handling code}
If an error occurs during upload, the UI does not display an error; it simply returns no flags or colors to the user. This is not a good user experience, but in this tutorial you do have the above mentioned.
Compile and run the project code, select an image and see that the progress bar has changed, and when the upload is complete, you will see the following information:
You have successfully uploaded the picture!
Original address
Alamofire uploading pictures Getting Started tutorial (top)