Sunday, 30 July 2017

Swift In Practice: Using Asset Catalog Identifiers


The usual way of handling things


Usually , we will be accessing image from asset catalogs as given below. For example, we have an asset catalog which contains three images.



Common Implementation


Whats wrong with the above usage


We will be using this hard coded image name informations in lot more places in our code. And any typo mistake will create bugs and the developer may unaware of this, since compiler will not capture typo errors in hard coded strings.

So how can we approach these problems in a more robust way and make our code more clean.

As a solution, we can use some global string constants. But is that adequate? the answer is No. See the following code.



It is clear, that UIImage designated initialiser can take any string constants , which will not show any errors during complication but will throw exception at run time. So , this can introduce some problems.

So its better to use strongly typed strings for asset catalog identifiers by making use of application specific enums. Also if we add a convenience initialiser to UIImage with a parameter named as "assetIdentifier" or something else according to your taste it will be perfect, Please refer the implementation given below.

Asset Catalog enums and UIImage convenience initialiser implementation




Asset Catalog Identifier Usage


Advantages

1. Typo errors in image names can be avoided since we are using enums. Which will result in compilation errors incase of Typo errors.

2. UIImage initialisers always returned with an image object.

3. Its easy identify unused images in your code by commenting an enum type. Which will not produce any compilation issue if the respective image is unused.

4. The class or file can be used a centralised source of your resources where you can find all of your image names.

References:

1. WWDC Video - Swift In Practice




Monday, 19 September 2016

iOS Overview: How to Create Local Notifications in iOS10

iOS Overview: How to Create Local Notifications in iOS10:

From iOS10 and onwards Apple deprecated UILocalNotification . We need to use UNNotificationRequest instead. UNNotificationRequest is def...

How to Create Local Notifications in iOS10

From iOS10 and onwards Apple deprecated UILocalNotification. We need to use UNNotificationRequest instead.

UNNotificationRequest is defined under UserNotifications framework. UNNotificationRequest consists of the following two objects or properties.

(a) UNNotificationContent
It defines the contents on the notification. For local notifications, create a UNMutableNotificationContent object and configure the contents of that object instead.

(b) UNNotificationTrigger
This is for defining an event that triggers the delivery of the notification.

Before triggering a notification, the first step from the App we should do is requesting authorisation for user interactions. The first time your app requests authorization, the user is alerted and given an opportunity to deny or grant that authorization.


Requesting authorization for user interactions in Objective C




Requesting authorization for user interactions in Swift




Creating a simple local notification in Objective C




Creating a simple local notification in Swift




Once the notification is triggered and the application is in background , notification UI will pop up with a sound.





Monday, 13 June 2016

iOS App Transport Security features in detail

What is App Transport Security ?

From iOS 9.0 and OS X 10.11 onwards Apple introduces a security feature called App Transport Security, which is enabled in apps by default. When ATS is enabled Apps will support only HTTPS connection to web servers, HTTP connections will fail with the following error in console.

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

To enable HTTP connections we need to configure the following keys in the App Info.plist file. This will disable ATS and HTTP connections will work as expected.

      <key>NSAppTransportSecurity</key>
      <dict>
           <key>NSAllowsArbitraryLoads</key><true/>
      </dict>


ATS is enabled by default in NSURLSession class and its APIS, the older NSURLConnection class also enforces ATS when you link against the iOS9.0 SDK or later.

if we are link our App against a SDK older than 1OS 9.0, ATS is disabled and the NSAppTransportSecurity key will be ignored.

By introducing Apple enforces the following security concerns.

  1. HTTP will be disabled by default
  2. HTTPS is not strong enough
  3. HTTPS must have “forward secrecy enabled”

There are some requirements to completely support ATS.

  • The App HTTP connections must use HTTPS.
  • The Transport Layer Security version must be TLS 1.2
  • TLS connection cipher suite must support forward secrecy (FS)
  • The leaf certificate must be signed with either RSA key with length 2048 bits or ECC key with size of atlas 256 bits


Depending upon the web servers and their capabilities we can have different configurations in the App Info.plist files.


For example.
To support ATS generally but allow HTTP connection to a specific server that does not support HTTPS, we can have the following config.


NSAppTransportSecurity
 NSExceptionDomains
        "media-server.example.com"
            NSExceptionAllowsInsecureHTTPLoads = YES


To use a secure connection to a Web server that uses an older version of TLS and does not support Forward Secrecy , we can use the following config.


NSAppTransportSecurity
    NSExceptionDomains
        "less-secure.example.com"
            NSExceptionRequiresForwardSecrecy = NO
            NSExceptionMinimumTLSVersion = "TLSv1.0"


To support ATS connections to the domain that we control , while allowing HTTP connections to all other URLS we can use the following config.


NSAppTransportSecurity
    NSExceptionDomains
        "domain-i-control.example.com"
            NSExceptionAllowsInsecureHTTPLoads = NO
            NSExceptionRequiresForwardSecrecy = YES
            NSExceptionMinimumTLSVersion = "TLSv1.2"
        "other-domain-i-control.example.com"
            NSExceptionAllowsInsecureHTTPLoads = NO
            NSExceptionRequiresForwardSecrecy = YES
            NSExceptionMinimumTLSVersion = "TLSv1.2"
    NSAllowsArbitraryLoads = YES


Debugging ATS Connections

1. First come option to debug a network problem is by using some packet sniffing tool like Burp Suite. (refer: https://portswigger.net/burp/)
2. In mac we can also use some inbuilt tools like tcpdump. To debug some high level protocols like HTTP we can use tcpflow.

To install tcpflow use the following link.
http://macappstore.org/tcpflow/

3. To do iOS Packet Tracing, we can use “Remote Virtual Interface”. Please refer the following link.
4. If we are using ATS support the data will not be directly visible in the above packet sniffing tools. We need to use “CFNetwork Diagnostic Logging”.

Please refer the link
https://developer.apple.com/library/ios/qa/qa1887/_index.html#//apple_ref/doc/uid/DTS40015177

5. In some cases it's useful to connect to a server and issue it commands for testing purposes. If the protocol is being used is TLS, your best option is the s_client subcommand of the openssl tool. An example command is given below.

openssl s_client -connect www.apple.com:443

Please refer: https://developer.apple.com/library/ios/technotes/tn2232/_index.html#//apple_ref/doc/uid/DTS40012884

6. Using the nscurl tool to diagnose ATS Connection Issues

In OS X v10.11 and later, you can use the /usr/bin/nscurl tool to help diagnose connection issues due to App Transport Security.

The command line 

/usr/bin/nscurl --ats-diagnostics https://apple.com


The most of the above contents are referred from the following Apple’s technical documentation.

https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html



Sunday, 29 March 2015

Swift: Debugging Techniques


There are mainly two functions available for printing the textual representation of objects and variables they are print( ) and println( ).

println( ) writes a newline character to the standard output.

Other functions available are debugPrintln() and debugPrint().

Examples of some functions are given below which can be used for advanced debugging.

println("Hello World!")


console output

Hello World!



var temp: String = "Test String"
println(temp)
debugPrintln(temp)


console output

Test String
"Test String"


For Customizing an object's textual representation we can override the methods debugDescription( )  or description( )


class ClassA: NSObject {
    var name: String = "unknown"
    
    override  var description: String {
        return "ClassA: \(name)"
    }
}

var tempA: ClassA = ClassA()
print(tempA.description)
println(tempA)


console output

ClassA: unknown
ClassA: unknown


Use toDebugString( ) and toString( ) which will returns the result of debugPrint and print into a string.


var str: String = toString(tempA)
println(str)


console output

ClassA: unknown


Use of precondition( ) and preconditionFailure( )

var value: String = ""
        
if value.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) == 0 {
    preconditionFailure("value is empty")
}


console output

fatal error: value is empty: file /Users/cramesh/Documents/My_Works/SwiftTutorial/SwiftTutorial/AppDelegate.swift, line 37

To identify an object we can use unsafeAddressOf( )

println(unsafeAddressOf(value))


console output

0x00007f8df251e480


Printing the class name and method name can be done as given below.


var className = NSStringFromClass(self.classForCoder)
println(className)

var methodName = NSStringFromSelector(__FUNCTION__) 
println(methodName)

or 

println(__FUNCTION__)
        



       







Wednesday, 1 October 2014

How to use UIAlertController instead of UIAlertView & UIActionsheet in iOS8


In iOS8 UIAlertController replaces UIActionsheet and UIAlertView. An AlertController can be created with a "title" and a "message".

We can set two styles to an AlertController. Which is given below.
(a)UIAlertControllerStyleActionSheet -  for configuring UIAlertController as an ActionSheet
(b)UIAlertControllerStyleAlert             -  for configuring UIAlertController as an Alert.

How to create an Alert/ActionSheet
  • Creating an AlertController object


  • Adding an Action

      
The handler block can be used to get the call back when “ok” button is pressed.
  • Presenting the alertController

How to create a simple Alert with OK button and a message

The following method will create a simple Alert in iOS8.

The Alert will be looking like as given below.




How to create a an Alert with two buttons

The Alert will be looking like as given below.





How to create an Alert with a TextField


The Alert will be looking like as given below.




How to create an Alert with two textfields

The Alert will be looking like as given below.




How to create an Actionsheet with two buttons

For creating an ActionSheet use "PreferredStyle" as "UIAlertControllerStyleActionSheet".


The ActionSheet will be looking like as given below.






Thursday, 14 August 2014

Accessing Elements Added in XIB without doing a IBOutlet Mapping

Probably most of you guys know about this. We can access a view element in a view controller by its tag number. This can be used in XIB's also.

For example:-

If we have added a UIButton in XIB , and we need to change its title dynamically from code. The traditional way of doing is creating a property with IBOutlet and mapping it to the corresponding element. Then change the title using the variable as given below.






But every time creating a property with IBOutlet is not necessary. We can do it the following way.

(Step 1) Add a tag to the corresponding element in the XIB file. Which is shown below in the case of UIButton.






(Step 2) Getting the UIButton element by accessing its tag value as given below.


    UIButton *button = (UIButton *)[self.view viewWithTag:234];
    if(button)
    {
        [button setTitle:@"Submit" forState:UIControlStateNormal];

    }


This can be applicable to most of the UIControl items also element like UILabel, UITableView, UIPickerView, UIView, which ever is having a tag property.