Showing posts with label iOS. Show all posts
Showing posts with label iOS. Show all posts

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

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



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.






Tuesday, 12 August 2014

YouTube Player for iOS

The older way of embedding youtube videos into iOS Applications was adding the video link into a UIWebView and loading it. Now google came up with a Helper library , by which we can embed youtube videos into UIView(internally UIWebView on top of UIView) and can play more easily.

The main advantage of this Helper library is , we will get more options and control over the video. By which we can do  Play, Pause, Stop and Video Skipping.

Steps for integrating YouTubeHelper library into existing Xcode Projects

1. Download the Library Source from GitHub.

2. Add the following files "YTPlayerView.h",  "YTPlayerView.m", and the "Assets" from library folder into your application project.

3. Create an IBOutlet property with "YTPlayerView" and map the corresponding "UIView" component in the XIB file. "YTPlayerView" is a subclass of "UIView", you need to change the class type of "UIView" component into "YTPlayerView" in the identity inspector.

4. Please refer the direct link for information.
https://developers.google.com/youtube/v3/guides/ios_youtube_helper#installation_manual

5. While running the App in iOS 7, incase if you encountered an issue as like the following
 "Received error rendering template: Error Domain=NSCocoaErrorDomain Code=258 "The operation couldn’t be completed. (Cocoa error 258.)"" , refer the following link.

http://stackoverflow.com/questions/23751817/try-to-play-you-tube-video-with-ytplayer-third-partry-libraray-in-ios

After Successfully integrating , use the following methods to load and play the youtube url.

(a)load video with youtube id.

(b)play a video after loading it.

(c)pause and stop the video

(d)Doings with delegate methods, the following "YTPlayerView" delegate methods can be used for having more control on top of YouTube player.

(e)getting the quality levels.

I have just embedded a youtube video into my "viewcontroller". The "UIView" size I have given is (640, 320) this is the size for a medium quality video.



 
Reference:-

Please refer the following google developer link for more info.
https://developers.google.com/youtube/v3/guides/ios_youtube_helper#installation_manual