{"id":8078,"date":"2015-11-25T07:25:04","date_gmt":"2015-11-25T07:25:04","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2015\/11\/25\/alamofire-alamofire\/"},"modified":"2022-08-30T15:03:02","modified_gmt":"2022-08-30T15:03:02","slug":"alamofire-alamofire","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2015\/11\/25\/alamofire-alamofire\/","title":{"rendered":"Alamofire\/Alamofire"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/raw.githubusercontent.com\/Alamofire\/Alamofire\/assets\/alamofire.png\" \/><\/p>\n<p>Alamofire is an HTTP networking library written in Swift.<\/p>\n<h2>Features<\/h2>\n<ul>\n<li>[x] Chainable Request \/ Response methods<\/li>\n<li>[x] URL \/ JSON \/ plist Parameter Encoding<\/li>\n<li>[x] Upload File \/ Data \/ Stream<\/li>\n<li>[x] Download using Request or Resume data<\/li>\n<li>[x] Authentication with NSURLCredential<\/li>\n<li>[x] HTTP Response Validation<\/li>\n<li>[x] Progress Closure &amp; NSProgress<\/li>\n<li>[x] cURL Debug Output<\/li>\n<li>[x] Comprehensive Unit Test Coverage<\/li>\n<li>[x] Complete Documentation<\/li>\n<\/ul>\n<h2>Requirements<\/h2>\n<ul>\n<li>iOS 7.0+ \/ Mac OS X 10.9+<\/li>\n<li>Xcode 6.3<\/li>\n<\/ul>\n<h2>Communication<\/h2>\n<ul>\n<li>If you <strong>need help<\/strong>, use Stack Overflow. (Tag \u2018alamofire\u2019)<\/li>\n<li>If you\u2019d like to <strong>ask a general question<\/strong>, use Stack Overflow.<\/li>\n<li>If you <strong>found a bug<\/strong>, open an issue.<\/li>\n<li>If you <strong>have a feature request<\/strong>, open an issue.<\/li>\n<li>If you <strong>want to contribute<\/strong>, submit a pull request.<\/li>\n<\/ul>\n<h2>Installation<\/h2>\n<blockquote>\n<p><strong>Embedded frameworks require a minimum deployment target of iOS 8 or OS X Mavericks.<\/strong><\/p>\n<p>To use Alamofire with a project targeting iOS 7, you must include all Swift files located inside the <code>Source<\/code> directory directly in your project. See the \u2018Source File\u2019 section for additional instructions.<\/p>\n<\/blockquote>\n<h3>CocoaPods<\/h3>\n<p>CocoaPods is a dependency manager for Cocoa projects.<\/p>\n<p>CocoaPods 0.36 adds supports for Swift and embedded frameworks. You can install it with the following command:<\/p>\n<pre><code>$ gem install cocoapods\n<\/code><\/pre>\n<p>To integrate Alamofire into your Xcode project using CocoaPods, specify it in your <code>Podfile<\/code>:<\/p>\n<pre><code>source 'https:\/\/github.com\/CocoaPods\/Specs.git'\nplatform :ios, '8.0'\nuse_frameworks!\n\npod 'Alamofire', '~&gt; 1.2'\n<\/code><\/pre>\n<p>Then, run the following command:<\/p>\n<pre><code>$ pod install\n<\/code><\/pre>\n<h3>Carthage<\/h3>\n<p>Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.<\/p>\n<p>You can install Carthage with Homebrew using the following command:<\/p>\n<pre><code>$ brew update\n$ brew install carthage\n<\/code><\/pre>\n<p>To integrate Alamofire into your Xcode project using Carthage, specify it in your <code>Cartfile<\/code>:<\/p>\n<pre><code>github \"Alamofire\/Alamofire\" &gt;= 1.2\n<\/code><\/pre>\n<h3>Manually<\/h3>\n<p>If you prefer not to use either of the aforementioned dependency managers, you can integrate Alamofire into your project manually.<\/p>\n<h4>Embedded Framework<\/h4>\n<ul>\n<li>Add Alamofire as a submodule by opening the Terminal, <code>cd<\/code>-ing into your top-level project directory, and entering the following command:<\/li>\n<\/ul>\n<pre><code>$ git submodule add https:\/\/github.com\/Alamofire\/Alamofire.git\n<\/code><\/pre>\n<ul>\n<li>\n<p>Open the new <code>Alamofire<\/code> folder, and drag the <code>Alamofire.xcodeproj<\/code> into the Project Navigator of your application\u2019s Xcode project.<\/p>\n<blockquote>\n<p>It should appear nested underneath your application\u2019s blue project icon. Whether it is above or below all the other Xcode groups does not matter.<\/p>\n<\/blockquote>\n<\/li>\n<li>\n<p>Select the <code>Alamofire.xcodeproj<\/code> in the Project Navigator and verify the deployment target matches that of your application target.<\/p>\n<\/li>\n<li>\n<p>Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the \u201cTargets\u201d heading in the sidebar.<\/p>\n<\/li>\n<li>\n<p>In the tab bar at the top of that window, open the \u201cGeneral\u201d panel.<\/p>\n<\/li>\n<li>\n<p>Click on the <code>+<\/code> button under the \u201cEmbedded Binaries\u201d section.<\/p>\n<\/li>\n<li>\n<p>You will see two different <code>Alamofire.xcodeproj<\/code> folders each with two different versions of the <code>Alamofire.framework<\/code> nested inside a <code>Products<\/code> folder.<\/p>\n<blockquote>\n<p>It does not matter which <code>Products<\/code> folder you choose from, but it does matter whether you choose the top or bottom <code>Alamofire.framework<\/code>.<\/p>\n<\/blockquote>\n<\/li>\n<li>\n<p>Select the top <code>Alamofire.framework<\/code> for iOS and the bottom one for OS X.<\/p>\n<blockquote>\n<p>You can verify which one you selected by inspecting the build log for your project. The build target for <code>Alamofire<\/code> will be listed as either <code>Alamofire iOS<\/code> or <code>Alamofire OSX<\/code>.<\/p>\n<\/blockquote>\n<\/li>\n<li>\n<p>And that\u2019s it!<\/p>\n<\/li>\n<\/ul>\n<blockquote>\n<p>The <code>Alamofire.framework<\/code> is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.<\/p>\n<\/blockquote>\n<h4>Source File<\/h4>\n<p>For application targets that do not support embedded frameworks, such as iOS 7, Alamofire can be integrated by adding all the Swift files located inside the <code>Source<\/code> directory (<code>Source\/*.swift<\/code>) directly into your project. Note that you will no longer need to <code>import Alamofire<\/code> since you are not actually loading a framework. Additionally, any of the calling conventions described in the \u2018Usage\u2019 section with the <code>Alamofire<\/code> prefix would instead omit it (for example, <code>Alamofire.request<\/code> becomes <code>request<\/code>), since this functionality is incorporated into the top-level namespace.<\/p>\n<h2>Usage<\/h2>\n<h3>Making a Request<\/h3>\n<pre><code>import Alamofire\n\nAlamofire.request(.GET, \"http:\/\/httpbin.org\/get\")\n<\/code><\/pre>\n<h3>Response Handling<\/h3>\n<pre><code>Alamofire.request(.GET, \"http:\/\/httpbin.org\/get\", parameters: [\"foo\": \"bar\"])\n         .response { (request, response, data, error) in\n                     println(request)\n                     println(response)\n                     println(error)\n                   }\n<\/code><\/pre>\n<blockquote>\n<p>Networking in Alamofire is done <em>asynchronously<\/em>. Asynchronous programming may be a source of frustration to programmers unfamiliar with the concept, but there are very good reasons for doing it this way.<\/p>\n<\/blockquote>\n<blockquote>\n<p>Rather than blocking execution to wait for a response from the server, a callback is specified to handle the response once it\u2019s received. The result of a request is only available inside the scope of a response handler. Any execution contingent on the response or data received from the server must be done within a handler.<\/p>\n<\/blockquote>\n<h3>Response Serialization<\/h3>\n<p><strong>Built-in Response Methods<\/strong><\/p>\n<ul>\n<li><code>response()<\/code><\/li>\n<li><code>responseString(encoding: NSStringEncoding)<\/code><\/li>\n<li><code>responseJSON(options: NSJSONReadingOptions)<\/code><\/li>\n<li><code>responsePropertyList(options: NSPropertyListReadOptions)<\/code><\/li>\n<\/ul>\n<h4>Response String Handler<\/h4>\n<pre><code>Alamofire.request(.GET, \"http:\/\/httpbin.org\/get\")\n         .responseString { (_, _, string, _) in\n                  println(string)\n         }\n<\/code><\/pre>\n<h4>Response JSON Handler<\/h4>\n<pre><code>Alamofire.request(.GET, \"http:\/\/httpbin.org\/get\")\n         .responseJSON { (_, _, JSON, _) in\n                  println(JSON)\n         }\n<\/code><\/pre>\n<h4>Chained Response Handlers<\/h4>\n<p>Response handlers can even be chained:<\/p>\n<pre><code>Alamofire.request(.GET, \"http:\/\/httpbin.org\/get\")\n         .responseString { (_, _, string, _) in\n                  println(string)\n         }\n         .responseJSON { (_, _, JSON, _) in\n                  println(JSON)\n         }\n<\/code><\/pre>\n<h3>HTTP Methods<\/h3>\n<p><code>Alamofire.Method<\/code> lists the HTTP methods defined in RFC 7231 \u00a74.3:<\/p>\n<pre><code>public enum Method: String {\n    case OPTIONS = \"OPTIONS\"\n    case GET = \"GET\"\n    case HEAD = \"HEAD\"\n    case POST = \"POST\"\n    case PUT = \"PUT\"\n    case PATCH = \"PATCH\"\n    case DELETE = \"DELETE\"\n    case TRACE = \"TRACE\"\n    case CONNECT = \"CONNECT\"\n}\n<\/code><\/pre>\n<p>These values can be passed as the first argument of the <code>Alamofire.request<\/code> method:<\/p>\n<pre><code>Alamofire.request(.POST, \"http:\/\/httpbin.org\/post\")\n\nAlamofire.request(.PUT, \"http:\/\/httpbin.org\/put\")\n\nAlamofire.request(.DELETE, \"http:\/\/httpbin.org\/delete\")\n<\/code><\/pre>\n<h3>Parameters<\/h3>\n<h4>GET Request With URL-Encoded Parameters<\/h4>\n<pre><code>Alamofire.request(.GET, \"http:\/\/httpbin.org\/get\", parameters: [\"foo\": \"bar\"])\n\/\/ http:\/\/httpbin.org\/get?foo=bar\n<\/code><\/pre>\n<h4>POST Request With URL-Encoded Parameters<\/h4>\n<pre><code>let parameters = [\n    \"foo\": \"bar\",\n    \"baz\": [\"a\", 1],\n    \"qux\": [\n        \"x\": 1,\n        \"y\": 2,\n        \"z\": 3\n    ]\n]\n\nAlamofire.request(.POST, \"http:\/\/httpbin.org\/post\", parameters: parameters)\n\/\/ HTTP body: foo=bar&amp;baz[]=a&amp;baz[]=1&amp;qux[x]=1&amp;qux[y]=2&amp;qux[z]=3\n<\/code><\/pre>\n<h3>Parameter Encoding<\/h3>\n<p>Parameters can also be encoded as JSON, Property List, or any custom format, using the <code>ParameterEncoding<\/code> enum:<\/p>\n<pre><code>enum ParameterEncoding {\n    case URL\n    case JSON\n    case PropertyList(format: NSPropertyListFormat,\n                      options: NSPropertyListWriteOptions)\n\n    func encode(request: NSURLRequest,\n                parameters: [String: AnyObject]?) -&gt;\n                    (NSURLRequest, NSError?)\n    { ... }\n}\n<\/code><\/pre>\n<ul>\n<li><code>URL<\/code>: A query string to be set as or appended to any existing URL query for <code>GET<\/code>, <code>HEAD<\/code>, and <code>DELETE<\/code> requests, or set as the body for requests with any other HTTP method. The <code>Content-Type<\/code> HTTP header field of an encoded request with HTTP body is set to <code>application\/x-www-form-urlencoded<\/code>. <em>Since there is no published specification for how to encode collection types, Alamofire follows the convention of appending <code>[]<\/code> to the key for array values (<code>foo[]=1&amp;foo[]=2<\/code>), and appending the key surrounded by square brackets for nested dictionary values (<code>foo[bar]=baz<\/code>).<\/em><\/li>\n<li><code>JSON<\/code>: Uses <code>NSJSONSerialization<\/code> to create a JSON representation of the parameters object, which is set as the body of the request. The <code>Content-Type<\/code> HTTP header field of an encoded request is set to <code>application\/json<\/code>.<\/li>\n<li><code>PropertyList<\/code>: Uses <code>NSPropertyListSerialization<\/code> to create a plist representation of the parameters object, according to the associated format and write options values, which is set as the body of the request. The <code>Content-Type<\/code> HTTP header field of an encoded request is set to <code>application\/x-plist<\/code>.<\/li>\n<li><code>Custom<\/code>: Uses the associated closure value to construct a new request given an existing request and parameters.<\/li>\n<\/ul>\n<h4>Manual Parameter Encoding of an NSURLRequest<\/h4>\n<pre><code>let URL = NSURL(string: \"http:\/\/httpbin.org\/get\")!\nvar request = NSURLRequest(URL: URL)\n\nlet parameters = [\"foo\": \"bar\"]\nlet encoding = Alamofire.ParameterEncoding.URL\n(request, _) = encoding.encode(request, parameters: parameters)\n<\/code><\/pre>\n<h4>POST Request with JSON-encoded Parameters<\/h4>\n<pre><code>let parameters = [\n    \"foo\": [1,2,3],\n    \"bar\": [\n        \"baz\": \"qux\"\n    ]\n]\n\nAlamofire.request(.POST, \"http:\/\/httpbin.org\/post\", parameters: parameters, encoding: .JSON)\n\/\/ HTTP body: {\"foo\": [1, 2, 3], \"bar\": {\"baz\": \"qux\"}}\n<\/code><\/pre>\n<h3>Caching<\/h3>\n<p>Caching is handled on the system framework level by <code>NSURLCache<\/code>.<\/p>\n<h3>Uploading<\/h3>\n<p><strong>Supported Upload Types<\/strong><\/p>\n<h4>Uploading a File<\/h4>\n<pre><code>let fileURL = NSBundle.mainBundle()\n                      .URLForResource(\"Default\",\n                                      withExtension: \"png\")\n\nAlamofire.upload(.POST, \"http:\/\/httpbin.org\/post\", file: fileURL)\n<\/code><\/pre>\n<h4>Uploading w\/Progress<\/h4>\n<pre><code>Alamofire.upload(.POST, \"http:\/\/httpbin.org\/post\", file: fileURL)\n         .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in\n             println(totalBytesWritten)\n         }\n         .responseJSON { (request, response, JSON, error) in\n             println(JSON)\n         }\n<\/code><\/pre>\n<h3>Downloading<\/h3>\n<p><strong>Supported Download Types<\/strong><\/p>\n<h4>Downloading a File<\/h4>\n<pre><code>Alamofire.download(.GET, \"http:\/\/httpbin.org\/stream\/100\", destination: { (temporaryURL, response) in\n    if let directoryURL = NSFileManager.defaultManager()\n                          .URLsForDirectory(.DocumentDirectory,\n                                            inDomains: .UserDomainMask)[0]\n                          as? NSURL {\n        let pathComponent = response.suggestedFilename\n\n        return directoryURL.URLByAppendingPathComponent(pathComponent!)\n    }\n\n    return temporaryURL\n})\n<\/code><\/pre>\n<h4>Using the Default Download Destination<\/h4>\n<pre><code>let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)\n\nAlamofire.download(.GET, \"http:\/\/httpbin.org\/stream\/100\", destination: destination)\n<\/code><\/pre>\n<h4>Downloading a File w\/Progress<\/h4>\n<pre><code>Alamofire.download(.GET, \"http:\/\/httpbin.org\/stream\/100\", destination: destination)\n         .progress { (bytesRead, totalBytesRead, totalBytesExpectedToRead) in\n             println(totalBytesRead)\n         }\n         .response { (request, response, _, error) in\n             println(response)\n         }\n<\/code><\/pre>\n<h3>Authentication<\/h3>\n<p>Authentication is handled on the system framework level by <code>NSURLCredential<\/code> and <code>NSURLAuthenticationChallenge<\/code>.<\/p>\n<p><strong>Supported Authentication Schemes<\/strong><\/p>\n<ul>\n<li>HTTP Basic<\/li>\n<li>HTTP Digest<\/li>\n<li>Kerberos<\/li>\n<li>NTLM<\/li>\n<\/ul>\n<h4>HTTP Basic Authentication<\/h4>\n<pre><code>let user = \"user\"\nlet password = \"password\"\n\nAlamofire.request(.GET, \"https:\/\/httpbin.org\/basic-auth\/\\(user)\/\\(password)\")\n         .authenticate(user: user, password: password)\n         .response {(request, response, _, error) in\n             println(response)\n         }\n<\/code><\/pre>\n<h4>Authentication with NSURLCredential<\/h4>\n<pre><code>let user = \"user\"\nlet password = \"password\"\n\nlet credential = NSURLCredential(user: user, password: password, persistence: .ForSession)\n\nAlamofire.request(.GET, \"https:\/\/httpbin.org\/basic-auth\/\\(user)\/\\(password)\")\n         .authenticate(usingCredential: credential)\n         .response {(request, response, _, error) in\n             println(response)\n         }\n<\/code><\/pre>\n<h3>Validation<\/h3>\n<p>By default, Alamofire treats any completed request to be successful, regardless of the content of the response. Calling <code>validate<\/code> before a response handler causes an error to be generated if the response had an unacceptable status code or MIME type.<\/p>\n<h4>Manual Validation<\/h4>\n<pre><code>Alamofire.request(.GET, \"http:\/\/httpbin.org\/get\", parameters: [\"foo\": \"bar\"])\n         .validate(statusCode: 200.. Serializer {\n        return { (request, response, data) in\n            if data == nil {\n                return (nil, nil)\n            }\n\n            var XMLSerializationError: NSError?\n            let XML = ONOXMLDocument(data: data, &amp;XMLSerializationError)\n\n            return (XML, XMLSerializationError)\n        }\n    }\n\n    func responseXMLDocument(completionHandler: (NSURLRequest, NSHTTPURLResponse?, ONOXMLDocument?, NSError?) -&gt; Void) -&gt; Self {\n        return response(serializer: Request.XMLResponseSerializer(), completionHandler: { (request, response, XML, error) in\n            completionHandler(request, response, XML as? ONOXMLDocument, error)\n        })\n    }\n}\n<\/code><\/pre>\n<h4>Generic Response Object Serialization<\/h4>\n<p>Generics can be used to provide automatic, type-safe response object serialization.<\/p>\n<pre><code>@objc public protocol ResponseObjectSerializable {\n    init?(response: NSHTTPURLResponse, representation: AnyObject)\n}\n\nextension Alamofire.Request {\n    public func responseObject(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -&gt; Void) -&gt; Self {\n        let serializer: Serializer = { (request, response, data) in\n            let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)\n            let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)\n            if response != nil &amp;&amp; JSON != nil {\n                return (T(response: response!, representation: JSON!), nil)\n            } else {\n                return (nil, serializationError)\n            }\n        }\n\n        return response(serializer: serializer, completionHandler: { (request, response, object, error) in\n            completionHandler(request, response, object as? T, error)\n        })\n    }\n}\n<\/code><\/pre>\n<pre><code>final class User: ResponseObjectSerializable {\n    let username: String\n    let name: String\n\n    required init?(response: NSHTTPURLResponse, representation: AnyObject) {\n        self.username = response.URL!.lastPathComponent\n        self.name = representation.valueForKeyPath(\"name\") as String\n    }\n}\n<\/code><\/pre>\n<pre><code>Alamofire.request(.GET, \"http:\/\/example.com\/users\/mattt\")\n         .responseObject { (_, _, user: User?, _) in\n             println(user)\n         }\n<\/code><\/pre>\n<p>The same approach can also be used to handle endpoints that return a representation of a collection of objects:<\/p>\n<pre><code>@objc public protocol ResponseCollectionSerializable {\n    class func collection(#response: NSHTTPURLResponse, representation: AnyObject) -&gt; [Self]\n}\n\nextension Alamofire.Request {\n    public func responseCollection(completionHandler: (NSURLRequest, NSHTTPURLResponse?, [T]?, NSError?) -&gt; Void) -&gt; Self {\n        let serializer: Serializer = { (request, response, data) in\n            let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)\n            let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)\n            if response != nil &amp;&amp; JSON != nil {\n                return (T.collection(response: response!, representation: JSON!), nil)\n            } else {\n                return (nil, serializationError)\n            }\n        }\n\n        return response(serializer: serializer, completionHandler: { (request, response, object, error) in\n            completionHandler(request, response, object as? [T], error)\n        })\n    }\n}\n<\/code><\/pre>\n<h3>URLStringConvertible<\/h3>\n<p>Types adopting the <code>URLStringConvertible<\/code> protocol can be used to construct URL strings, which are then used to construct URL requests. <code>NSString<\/code>, <code>NSURL<\/code>, <code>NSURLComponents<\/code>, and <code>NSURLRequest<\/code> conform to <code>URLStringConvertible<\/code> by default, allowing any of them to be passed as <code>URLString<\/code> parameters to the <code>request<\/code>, <code>upload<\/code>, and <code>download<\/code> methods:<\/p>\n<pre><code>let string = NSString(string: \"http:\/\/httpbin.org\/post\")\nAlamofire.request(.POST, string)\n\nlet URL = NSURL(string: string)!\nAlamofire.request(.POST, URL)\n\nlet URLRequest = NSURLRequest(URL: URL)\nAlamofire.request(.POST, URLRequest) \/\/ overrides `HTTPMethod` of `URLRequest`\n\nlet URLComponents = NSURLComponents(URL: URL, resolvingAgainstBaseURL: true)\nAlamofire.request(.POST, URLComponents)\n<\/code><\/pre>\n<p>Applications interacting with web applications in a significant manner are encouraged to have custom types conform to <code>URLStringConvertible<\/code> as a convenient way to map domain-specific models to server resources.<\/p>\n<h4>Type-Safe Routing<\/h4>\n<pre><code>extension User: URLStringConvertible {\n    static let baseURLString = \"http:\/\/example.com\"\n\n    var URLString: String {\n        return User.baseURLString + \"\/users\/\\(username)\/\"\n    }\n}\n<\/code><\/pre>\n<pre><code>let user = User(username: \"mattt\")\nAlamofire.request(.GET, user) \/\/ http:\/\/example.com\/users\/mattt\n<\/code><\/pre>\n<h3>URLRequestConvertible<\/h3>\n<p>Types adopting the <code>URLRequestConvertible<\/code> protocol can be used to construct URL requests. <code>NSURLRequest<\/code> conforms to <code>URLRequestConvertible<\/code> by default, allowing it to be passed into <code>request<\/code>, <code>upload<\/code>, and <code>download<\/code> methods directly (this is the recommended way to specify custom HTTP header fields or HTTP body for individual requests):<\/p>\n<pre><code>let URL = NSURL(string: \"http:\/\/httpbin.org\/post\")!\nlet mutableURLRequest = NSMutableURLRequest(URL: URL)\nmutableURLRequest.HTTPMethod = \"POST\"\n\nlet parameters = [\"foo\": \"bar\"]\nvar JSONSerializationError: NSError? = nil\nmutableURLRequest.HTTPBody = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: &amp;JSONSerializationError)\nmutableURLRequest.setValue(\"application\/json\", forHTTPHeaderField: \"Content-Type\")\n\nAlamofire.request(mutableURLRequest)\n<\/code><\/pre>\n<p>Applications interacting with web applications in a significant manner are encouraged to have custom types conform to <code>URLRequestConvertible<\/code> as a way to ensure consistency of requested endpoints. Such an approach can be used to abstract away server-side inconsistencies and provide type-safe routing, as well as manage authentication credentials and other state.<\/p>\n<h4>API Parameter Abstraction<\/h4>\n<pre><code>enum Router: URLRequestConvertible {\n    static let baseURLString = \"http:\/\/example.com\"\n    static let perPage = 50\n\n    case Search(query: String, page: Int)\n\n    \/\/ MARK: URLRequestConvertible\n\n    var URLRequest: NSURLRequest {\n        let (path: String, parameters: [String: AnyObject]?) = {\n            switch self {\n            case .Search(let query, let page) where page &gt; 1:\n                return (\"\/search\", [\"q\": query, \"offset\": Router.perPage * page])\n            case .Search(let query, _):\n                return (\"\/search\", [\"q\": query])\n            }\n        }()\n\n        let URL = NSURL(string: Router.baseURLString)!\n        let URLRequest = NSURLRequest(URL: URL.URLByAppendingPathComponent(path))\n        let encoding = Alamofire.ParameterEncoding.URL\n\n        return encoding.encode(URLRequest, parameters: parameters).0\n    }\n}\n<\/code><\/pre>\n<pre><code>Alamofire.request(Router.Search(query: \"foo bar\", page: 1)) \/\/ ?q=foo+bar&amp;offset=50\n<\/code><\/pre>\n<h4>CRUD &amp; Authorization<\/h4>\n<pre><code>enum Router: URLRequestConvertible {\n    static let baseURLString = \"http:\/\/example.com\"\n    static var OAuthToken: String?\n\n    case CreateUser([String: AnyObject])\n    case ReadUser(String)\n    case UpdateUser(String, [String: AnyObject])\n    case DestroyUser(String)\n\n    var method: Alamofire.Method {\n        switch self {\n        case .CreateUser:\n            return .POST\n        case .ReadUser:\n            return .GET\n        case .UpdateUser:\n            return .PUT\n        case .DestroyUser:\n            return .DELETE\n        }\n    }\n\n    var path: String {\n        switch self {\n        case .CreateUser:\n            return \"\/users\"\n        case .ReadUser(let username):\n            return \"\/users\/\\(username)\"\n        case .UpdateUser(let username, _):\n            return \"\/users\/\\(username)\"\n        case .DestroyUser(let username):\n            return \"\/users\/\\(username)\"\n        }\n    }\n\n    \/\/ MARK: URLRequestConvertible\n\n    var URLRequest: NSURLRequest {\n        let URL = NSURL(string: Router.baseURLString)!\n        let mutableURLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path))\n        mutableURLRequest.HTTPMethod = method.rawValue\n\n        if let token = Router.OAuthToken {\n            mutableURLRequest.setValue(\"Bearer \\(token)\", forHTTPHeaderField: \"Authorization\")\n        }\n\n        switch self {\n        case .CreateUser(let parameters):\n            return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0\n        case .UpdateUser(_, let parameters):\n            return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0\n        default:\n            return mutableURLRequest\n        }\n    }\n}\n<\/code><\/pre>\n<pre><code>Alamofire.request(Router.ReadUser(\"mattt\")) \/\/ GET \/users\/mattt\n<\/code><\/pre>\n<h2>FAQ<\/h2>\n<h3>When should I use Alamofire?<\/h3>\n<p>If you\u2019re starting a new project in Swift, and want to take full advantage of its conventions and language features, Alamofire is a great choice. Although not as fully-featured as AFNetworking, Alamofire is much nicer to work with, and should satisfy the vast majority of networking use cases.<\/p>\n<blockquote>\n<p>It\u2019s important to note that two libraries aren\u2019t mutually exclusive: AFNetworking and Alamofire can peacefully exist in the same code base.<\/p>\n<\/blockquote>\n<h3>When should I use AFNetworking?<\/h3>\n<p>AFNetworking remains the premiere networking library available for OS X and iOS, and can easily be used in Swift, just like any other Objective-C code. AFNetworking is stable and reliable, and isn\u2019t going anywhere.<\/p>\n<p>Use AFNetworking for any of the following:<\/p>\n<ul>\n<li>UIKit extensions, such as asynchronously loading images to <code>UIImageView<\/code><\/li>\n<li>TLS verification, using <code>AFSecurityManager<\/code><\/li>\n<li>Situations requiring <code>NSOperation<\/code> or <code>NSURLConnection<\/code>, using <code>AFURLConnectionOperation<\/code><\/li>\n<li>Network reachability monitoring, using <code>AFNetworkReachabilityManager<\/code><\/li>\n<li>Multipart HTTP request construction, using <code>AFHTTPRequestSerializer<\/code><\/li>\n<\/ul>\n<h3>What\u2019s the origin of the name Alamofire?<\/h3>\n<p>Alamofire is named after the Alamo Fire flower, a hybrid variant of the Bluebonnet, the official state flower of Texas.<\/p>\n<h2>Credits<\/h2>\n<p>Alamofire is owned and maintained by the Alamofire Software Foundation.<\/p>\n<h2>License<\/h2>\n<p>Alamofire is released under the MIT license. See LICENSE for details.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Alamofire is an HTTP networking library written in Swift. Features [x] Chainable Request \/ Response methods [x] URL \/ JSON \/ plist Parameter Encoding [x] Upload File \/ Data \/ Stream [x] Download using Request or Resume data [x] Authentication with NSURLCredential [x] HTTP Response Validation [x] Progress Closure &amp; NSProgress [x] cURL Debug Output [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-8078","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/8078","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=8078"}],"version-history":[{"count":1,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/8078\/revisions"}],"predecessor-version":[{"id":8642,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/8078\/revisions\/8642"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=8078"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=8078"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=8078"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}