How to Respond to an Authentication Challenge | iOS

How to Respond to an Authentication Challenge

If a session requires authentication it creates authentication challenge

 URLSession:task:didReceiveChallenge:completionHandler: 

in order for the connection to continue, the delegate has three options.

  • Provide authentication credentials
  • Attempt to continue without credentails
  • Cancel the authentication request.

NSURLProtectionSpace will give all information about the authentication type and failure if any attempts failed earlier.

Providing Credentials

To attempt to authenticate, the application should create an NSURLCredential object with authentication information of the form expected by the server. You can determine the server’s authentication method by calling authenticationMethod on the protection space.

  • HTTP basic authentication (NSURLAuthenticationMethodHTTPBasic) requires a user name and password. P
  • HTTP digest authentication (NSURLAuthenticationMethodHTTPDigest), like basic authentication, requires a user name and password.withcredentialWithUser:password:persistence:.
  • Client certificate authentication (NSURLAuthenticationMethodClientCertificate) requires the system identity and all certificates needed to authenticate with the server. Create an NSURLCredential object.
  • Server trust authentication (NSURLAuthenticationMethodServerTrust) requires a trust provided by the protection space of the authentication challenge.

Continuing Without Credentials

If the delegate chooses not to provide a credential for the authentication challenge, it can attempt to continue without one.

NSURLSessionAuthChallengePerformDefaultHandling processes the request as though the delegate did not provide a delegate method to handle the challenge.

  • NSURLSessionAuthChallengeRejectProtectionSpace rejects the challenge. Depending on the authentication types allowed by the server’s response, the URL loading class may call this delegate method more than once, for additional protection spaces.

Canceling the Connection

The delegate may also choose to cancel the authentication challenge, by passing NSURLSessionAuthChallengeCancelAuthenticationChallenge to the provided completion handler block.

Dependency Injection | Swift | Quick Note

A short answer is, it’s scary terms for a very simple idea!!! See this lines of code.

class Engine {

}

class Car {
    let engine: Engine? = nil
    init() {
        self.engine = Engine()
    }
}

we are creating dependency internally but the object can be also received from outside with lots of benefits like the object become instantly testable, Testing becomes possible without any frameworks, No runtime effects, This makes the whole system more loosely coupled.

class Car {
    let engine: Engine? = nil
    init(engine: Engine) {
        self.engine = engine
    }
}

There are three common types of dependency injections.

Setter, Interface, Constructor based.

In iOS Constructor based is preferable one, it’s when dependency passed to the client in the initializer and don’t change during the whole client life and the biggest advantage of this type could be that it makes the violation of the single responsibility programming principle, if an object takes all dependencies in the initializer and if it has more than three parameters so it means refactoring is needed.

Thanks for reading!!!

Swift | iOS 10 | Orientation | Quick Notes

When it comes to handling Orientation in iOS App Development, creates little confusion because with every release their minor changes. so let’s see who does it works with iOS 10.

First thing if you want to support all Orientations just enable it from here.

Screen Shot 2017-08-02 at 3.40.51 PM.png

Second, if the requirement is something like, need Orientation support only for few Controllers. make sure you have followed the first case and just this code snippet for enabling/disable it for each view.

override var shouldAutorotate: Bool {
    return true
}

its simple as its looking just return `true` if you want to support orientation for controller else return `false`. Next concern is if you are returning true then you have an option to specify the orientations as well just implement this code snippet.

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.all
} 

Click `UIInterfaceOrientationMask` to see the options so just return whatever you want to use. Sounds good?

public struct UIInterfaceOrientationMask : OptionSet {
    public init(rawValue: UInt)
    public static var portrait: UIInterfaceOrientationMask { get }
    public static var landscapeLeft: UIInterfaceOrientationMask { get }
    public static var landscapeRight: UIInterfaceOrientationMask { get }
    public static var portraitUpsideDown: UIInterfaceOrientationMask { get }
    public static var landscape: UIInterfaceOrientationMask { get }
    public static var all: UIInterfaceOrientationMask { get }
    public static var allButUpsideDown: UIInterfaceOrientationMask { get }
}

Thank you for reading.

Make your iOS apps more secure with SSL pinning

SSL/Certificate pinning plays a very critical role in building highly secure mobile apps which users will be able to use even in countless insecure wireless network connections.

At a glance, Idea is the SSL(Secure Socket Layer) ensures the encrypted client-server communication over HTTPS. The encryption is based on PKI (Public Key Infrastructure) and a session key. The session key was introduced because encrypting and decrypting a public/private key uses a lot of processing time/power/space for sure it will slow down the process.

MIMT, Yes SSL Communication is very secure but the man-in-the-middle attack still poses an exact threat using ARP cache poisoning and DNS spoofing.

SSL/Certificate Pinning, ensure that the app communicates only with the designated server only and the prerequisites for SSL pinning is saving the target’s server SSL certificate within the app bundle.

SSL pinning is implemented within the

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void

and here are the steps we need to follow.

  • First read the server trust and server certificate.

let serverTrust = challenge.protectionSpace.serverTrust
let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0

  • Now set the policies for server validation, previous failure count etc.

SecTrustSetPolicies(serverTrust, SecPolicyCreateSSL(true, (challenge.protectionSpace.host as CFString)))

  • Start policies validation, convert server certificate in Data and get the local certificate from bundle.

 let remoteCertificateData = SecCertificateCopyData(certificate)
 let pathToCert = Bundle.main.path(forResource: “certificate”, ofType: “cer”

At last compare your policies result and local certificate data with your server certificate data, if everything goes well complete the challange with credentail.

completionHandler(.UseCredential, credential)

Otherwise cancel the authentication and pass nil as credentails.

completionHandler(.CancelAuthenticationChallenge, nil)

Thank you reading, you can download the source code from GIT and also learn contribute about iOS Security.

iOS | Bounds vs Frame ?

Everyone talk about bounds and frame during the interview for sure. lets make it little easy.

The Bounds of a view is recentagle, expressed as location coordinates (x,y) and also the size (height, width) relative to the own coordinate system.

The Frame of a view is recentagle, expressed as location coordinates (x,y) and also the size (height, width) relative to the its superview.

So for example lets say if you have UILabel on top of your UIView that has size of (100×100) with thelocation coordinates (10,10). so here is the Swift code.

override func viewDidLoad() {
        super.viewDidLoad()

        //Bounds
        print("label.bounds.origin.x    = \(label.bounds.origin.x)")
        print("label.bounds.origin.y    = \(label.bounds.origin.y)")
        print("label.bounds.size.height = \(label.bounds.size.height)")
        print("label.bounds.size.width  = \(label.bounds.size.width)")

        //Frame
        print("label.frame.origin.x    = \(label.frame.origin.x)")
        print("label.frame.origin.y    = \(label.frame.origin.y)")
        print("label.frame.size.height = \(label.frame.size.height)")
        print("label.frame.size.width  = \(label.frame.size.width)")
    }

So for the both cases size(height, width) will be same only the position (x,y) will be different as in case of bounds its relative to its own view and for frame its relative to superview. for more please see the below image(source: slideshare, CS 193P lecture).

Screen Shot 2017-05-17 at 11.12.59 AM

iOS Concurrency | Introduction | Options

Concurrency is two sided-weapon, that you should master and learn how to use because it will help you to write efficient code with fast execution but if you are misusing it, then results will be poor app performance, crashes etc.

So before writing code think about the problem, why do we need that and which API do you need to resolve it.

In iOS, we have different APIs that we can be used. But wait here the question is why do we need Concurrency?

  • Utilize iOS Hardware: Now all of the iOS devices are with multi-core processors that allow developers to execute multiple tasks parallel. So here we can earn lots of benefits.
  • Better User Experience: Code for call multiple web services, handle IO and some heavy tasks etc will freeze UI and make your app nonresponsive so if as a user I face this I will close the app for sure, but with concurrency, all tasks can be done in the background without hanging the main thread.
  • APIs like NSOperation and Dispatch Queues makes it really easy: Earlier creating and managing threads is not easy that’s the reason everyone gets scared when they hear about concurrency. Another major advantage of APIs is, it will also help you to manage synchronization to avoid the race condition, it happens with two threads try to access the shared resource.

Properties | Swift | iOS | Stored

Properties associate value with a paticular class, structure or enumeration. Stored Properties (provided by class, struct and enum) store constant and variable values as part of instance, whereas Computed Properties (provided by class and struct only) calculate a value. Properties can also be associated with type itself its called Type Properties. Apart from that we can add observers to monitor the changes in a property’s value there you can response to your custom actions, we can add it to Stored Properties and also property that a subclass.

Stored Properties

Simplest form, its a constant or variable that is stored as a part of an instance of a particuler class, struct or enum.

struct Box  {
    var height  : Int
    let width   : Int
}

var box1 = Box(height: 101, width: 10)

It can be either Variable stored property (introduced by var) or Constant stored property(introduced by let). if its Variable stored property than we can set initial value during initialization and if Constant stored property without default value than yes as well.

Lazy Stored Properties

Whose initial values is not calculated until the first time it is used. they are useful when the initial value for a property is dependent on other factors or sometime if the initial value for a property requires complex or computationally expensive setup that should not be performed unless it is needed.

class DataImporter  {
    /*
     This class is responsible for fetching and holding the file data.
    */
    var fileName = "data.json"
}

class DataManager   {
    var data = [String]()
    lazy var importer = DataImporter()
}

let dManager = DataManager()
dManager.data.append("One")
dManager.data.append("two")

Now here the interseting part is till now importer property is not created. because is marked as lazy so the property is only created when the importer property is first accessed.