Mobile Development

Ilya Loshkarev


Remote Data Cost

  • Battery Life
  • System Perfomance
  • Data Transfer Cost
  • Optimize Assets
  • Cache Data

Reachability Check

							var flags: SCNetworkReachabilityFlags = []
							if !SCNetworkReachabilityGetFlags(hostRoute, &flags) {
								return false
							if flags.contains(.reachable){
								return true

The reachability API helps to determine if
a remote host is reachable

App Transport Security

Starting in iOS 9.0 and OS X v10.11, a new security feature called App Transport Security (ATS) is enabled by default for all HTTP connections made with NSURLSession. ATS requires that HTTP connections use HTTPS.

Apple Docs

Disabling ATS

						NSAppTransportSecurity : Dictionary
							NSAllowsArbitraryLoads : YES      // http everywhere - unsafe!

Specify domains that are allowed to have http connections:

						NSAppTransportSecurity : Dictionary : Dictionary
								NSAllowsArbitraryLoads : YES // allows http in the domain

iOS 10.0 introduced NSAllowsArbitraryLoadsInMedia and

URL Session

URL Session Diagram

Dispatch queue for remote requests on top of TCP/IP sockets

Shared Session

						  let session = URLSession.shared
						  let url = URL(string: "")
						  let task = session.dataTask(with: url) {
						    data, response, error in
						    /* handle response */
						  task.resume() // start task

Default uncofigurable session for handling basic requests

Session Configurtion

  • Default default session configuration
  • Ephimeral doesn't write to cache or cookies
  • Background allows background upload and download

Session Tasks

  • Data Task sends and receives data using NSData objects
    session.dataTask(with: URL)
  • Upload Task sends data and supports background uploads
    session.uploadTask(with: URLRequest, from: Data)
  • Download Task retrieves data and supports background downloads and uploads
    session.downloadTask(with: URL)

Session Delegate

  • URLSessionDelegate
    Authentication on a session-level, Session errors
  • URLSessionTaskDelegate
    Authentication requests, Redirects, Completion
  • URLSessionDataDelegate
    Recieved Data, Should use cache
  • URLSessionDownloadDelegate
    Download has finished, started, progressed

Building a Session

						  let config = URLSessionConfiguration.default
						  config.allowsCellularAccess = false
						  config.timeoutIntervalforRequest = 30.0
						  let session = URLSession(configuration: config)
						  let url = URL(string: "")
						  let task = session.dataTask(with: url) {
						      data, response, error in
						      /* handle response */
						  task.resume() // start task

If no delegate is assigned to a session,
a completion handler must be provided to recieve data

HTTP Response

						  let task = session.dataTask(with: url) {
						      data, response, error in
						      if let httpResponse = response as? HTTPURLResponse {
						          switch httpResponse.statusCode {
						            case 200: print("OK")
						            case 404: print("Not found")
						              print("Something else")

HTTP Headers

HTTP headers can be setup as part of each request or
as default headers in configuration

						  let config = URLSessionConfiguration.default
						  config.allowsCellularAccess = false
						  config.timeoutIntervalforRequest = 30.0
						  config.httpAdditionalHeaders["Some Header"] = someValue

Download Data

						  let request = URLRequest( url: myUrl)
						  request.httpMethod = "GET"
						  /* set any additional HTTP Headers here */
						  let task = session.dataTask(with: request ){
						      data, response, error in
						      /* handle response */

Upload Data

						  let request = URLRequest(url: myUrl)
						  request.httpMethod = "POST"
						  /* set any additional HTTP Headers here */
						  let task = session.uploadTask(with: request, from: someData ){
						      data, response, error in
						      /* handle response */

URL with Parameters

						  let urlComponents = URLComponents(
						      URL: baseUrl,
						      resolvingAgainstBaseURL: true)!
						  urlComponents.path = relativePathString
						  urlComponents.query = parametersString.addingPercentEncoding(
						      withAllowedCharacters: .urlHostAllowed)
						  let request = URLRequest(url: urlComponents.url!)


class to embed web content in your app

							let webView = UIWebView()
							let request = URLRequest(url: myUrl)

Web​View objects can be used to display
Keynote, PDF, and Pages documents



HTTP networking library

  • Chainable Request / Response Methods
  • URL / JSON / plist Parameter Encoding
  • Upload File / Data / Stream / MultipartFormData
  • HTTP Response Validation


Dependency manager for Cocoa projects

              > sudo gem install cocoapods
              // initialize
              > pod init
              // create pod file
              > echo "source ''
              platform :ios, '10.0'
              target '<Your Target Name>' do
                pod 'Alamofire', '~> 4.0'
              end" > Podfile
              // install all dependences
              > pod install

Simple Request

              Alamofire.request("").response {
                  response in
                  print(response.request)  // original URL request
                  print(response.response) // HTTP URL response
                  print(     // server data
                  print(response.result)   // result of response serialization

Responses are handled asynchronously

Response Validation

                  .validate(statusCode: 200..<300)
                  .validate(contentType: ["application/json"])
                  .responseData { response in
                      switch response.result {
                      case .success:
                          print("Validation Successful")
                      case .failure(let error):

Request with Parameters

              let parameters: Parameters = [
                  "foo": "bar",
                  "baz": ["a", 1],

                  parameters: parameters, encoding: URLEncoding.default)
                  parameters: parameters, encoding: URLEncoding.httpBody)
              Alamofire.request("", method: .post,
                  parameters: parameters, encoding: JSONEncoding.default)

Parameters can be encoded into
URL, HTTP body or JSON

Additional Headers

              let headers: HTTPHeaders = [
                  "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
                  method: .post, headers: headers)


AAA Protocols

  • Authentication – confirming your identity
  • Authorization – confirming your right to make a request
  • Accounting – keeping track of user requests

Basic Access Authentication

Implemented by Apache modules

Unauthenticated requests return a response with
401 Unauthorized status and a WWW-Authenticate field

              WWW-Authenticate: Basic realm = "User Visible Realm"

Client sends authentication credentials
using HTTP header field Authorization

              Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

Session Level Authentication

              func urlSession(_ session: URLSession, task: URLSessionTask,
                  didReceive challenge: URLAuthenticationChallenge,
                  completionHandler: @escaping (URLSession.AuthChallengeDisposition,
                  URLCredential?) -> Void)
                  let credential = URLCredential( // credentials to send
                      user: "test",
                      password: "test",
                      persistence: .forSession)
                  completionHandler(.useCredential, credential)

If your authentication is a default Apache authentication
implementation of didReceiveChallenge delegate is prefered

Request Level Authentication

              let authData = Data("\(user):\(password)".utf8)
              let base64String = authData.base64EncodedString()
              let request = URLRequest( url: myUrl)
              request.addValue("Basic \(base64String)",
                  forHTTPHeaderField: "Authorization")

Alamofire Request Authentication

                  .authenticate(user: user, password: password)
                  .responseJSON { response in

Open Authorisation Protocol

2010 – ver. 2.0

Provides secure deligated access on behalf of resource owner

OAuth Logo

Peudo Authentication


3-legged Authorization

  1. Register
  2. Receive Authorization Token
  3. Ask for Authorised Access with Auth.Token
  4. Receive Access Token
  5. Access APIs with given token

Theese two tokens could be given by servers differnet from an API provider

Ask for Authentication Token

              func startOAuth2Login() {
                  let authPath = "

                  if let authURL = URL(string: authPath) {

openURL is a system-wide call for an App
that is registered for the requested URL Scheme

Browser window will pop up and ask the user
to allow access for our app

Handling URL Callbacks

              URL types
                Item 0
                  URL Schemes
                    Item 0 - yourURLScheme
                  URL identifier - yourAppID

iOS app can be register to handle URL Scheme calls

Most OAuth2 systems allow for an URL callback

Receive Authentication Token

              class AppDelegate: UIResponder, UIApplicationDelegate {
                  func application(application: UIApplication, handleOpenURL url: URL) -> Bool {
                      // url == yourURLScheme://...&code=12345&...
                      proceedOAuth2Access(with: getOAuth2Token(url))
                      return true

Your app is getting a callback to handle URL with Auth.Token

Ask for Access Token

              func getOAuth2Token(_ url: URL) -> String? {
                /* parse URL Components for code */
              func proceedOAuth2Access(with authToken: String?) {
                  guard let receivedToken = authToken { return }
                  let getTokenPath = ""
                  let tokenParams = [ "client_id": clientID,
                      "client_secret": clientSecret,
                      "code": receivedToken ]
                  Alamofire.request(.POST, getTokenPath, parameters: tokenParams)
                    .responseString { (request, response, results, error) in
                     /*  handle response to extract access token */

Alamofire Adapter & Retrier

              let oauthHandler = OAuth2Handler(
                  clientID: "12345678",
                  baseURLString: baseURLString,
                  accessToken: "abcd1234",
                  refreshToken: "ef56789a"

              let sessionManager = SessionManager()
              sessionManager.adapter = oauthHandler
              sessionManager.retrier = oauthHandler

              let urlString = "\(baseURLString)/some/endpoint"

Alamofire proides abstractions to handle
some of the OAuth2 interactions on the session-level

Restful API

Representational State Transfer


Non standartized protocol that utilises HTTP headers and JSON data to access server endpoints

Expected RESTful API

Entity/id select by idinsert with id update with iddelete with id
Entity select all/filteredinsert all/filtered update all/filtereddelete all/filtered

Query Parameters
with URLSession

  • URL Encoded
    urlComponents.query = parametersString
  • HTTP Headers
    request.addValue(key, parameters[key])
  • HTTP Body
    request.body = parametersString

Query Parameters
with Alamofire

  • URL Encoded
    									Alamofire.request("", parameters: parameters,
    										encoding: URLEncoding.queryString)
  • HTTP Headers
    										headers: parameters)
  • HTTP Body
    									Alamofire.request("", parameters: parameters,
    										encoding: URLEncoding.httpBody)

Javascript Object Notation

									  "firstName": "Иван",
									  "lastName": "Иванов",
									  "address": {
									    "streetAddress": "Московское ш., 101, кв.101",
									    "city": "Ленинград",
									    "postalCode": 101101
json logo

JSON Serialization

							// Serialize any KVC compliant object to JSON string
							let data = person, options:[])
							// Deserialize string into NSObject
							if let json = ( try? JSONSerialization.jsonObject(with: data!,
									options: []) ) as? [String: AnyObject]
								print(json["firstName"] as? String)

Object Mapper

Simple JSON Object mapping written in Swift

  • Mapping JSON to objects
  • Mapping objects to JSON
  • Nested Objects
  • Custom transformations during mapping


a protocol, defines mapping of JSON parameters to object properties

							class Temperature: Mappable {
								var celsius: Float
								required init?(map: Map) {
									guard let c = map.JSON["celsius"] else { return nil }
									celsius = c
								mutating func mapping(map: Map) {
									celsius  <- map["celsius"]

Alamofire Object Mapper

						Alamofire.request(url).responseObject {
							(response: DataResponse<Temperature>) in

Database Synchronization


Automatically maps CoreData objects to JSON

							Sync.changes( json["data"] as! [[String : Any]],
									inEntityNamed: "Data",
									dataStack: self.dataStack) {
								error in

Related Resources