Tuesday, September 27, 2016

iOS 10 and xcode 8 tip

1.  xocode shows "development cannot be enabled while your device is locked, Please unlock your device and reattach. (0xE80000E2).

If your ios device is already unlocked and connected to mac and still get the error from xcode 8 after upgrading to ios 10, then the mac is not trusted by the device.
To fix it, first disconnect device to mac and then go to ios settings app, and open general->reset->Reset Location & Privacy.
Then connect device to mac and when prompted, set select trust the mac


2. Desymbolize the crash log using external symbol file
It has been much better to use xcode 8 to desymbolize the crash log. Just download the symbol file at any place, for example, the download folder and it seems xcode will do a full disk search to find the right symbol file.
Then from the xocde view device log screen, select the crash log and right click and select "re-symbolicate log", then it will update the symbolized file in the right panel.


3. in swift 2, raw NSData bytes can be converted to UnsafeMutablePoint<> directly as below sample

let derivedKey = NSMutableData(length: kCCKeySizeAES128);
UnsafeMutablePointer<UInt8>(derivedKey!.mutableBytes

However, in swift 3, that will cause an build error of "Cannot invoke initializer for type 'UnsafeMutablePointer<UInt8>' with an argument list of type '(UnsafeMutableRawPointer)'.
To fix it, just need to call assumeingMemoryBound method as below
let derivedKey = NSMutableData(length: kCCKeySizeAES128);
UnsafeMutablePointer<UInt8>(derivedKey!.mutableBytes.assumingMemoryBound(to:UInt8.self)),


4. avoid result unused warning for swift 3
in swift 2, calling a function without using its return value is normal. But it will generate a result unused warning in swift 3. To avoid the compile warning, just set the return value to _ as shown below

 _ = (UIApplication.shared.delegate as! AppDelegate).passwordManager.getPasswordItemList(currentCategory)

Monday, September 26, 2016

Steps to run xcode 8 side by side with xcode 7

The below steps can be used to install xcode 8 side by side with xcode 7

1. open Finder and go to Application folder, right clicking on Xcode, and select "duplicate", once it is done, rename "Xcode Copy" to "Xcode7"
2. Somehow the xcode 8 does not appear in the App Store update list. So you need manually to get it. Just open App Store app, and searching for "xcode",  then getting the Xcode 8 from there.
3. once the the XCode 8 installed, restarting the MAC.
4. By default, when starting xcode, xcode 8 will be selected. If you want to use xcode 7, just open Finder, and go to Application folder to start xCode7 from there.
5. Note, if you also use command line tools to build xcode project, you will need to switch the xcode path to the right version to do that by running the below command from terminal

xcode-select --print-path
//show the current selected xcode command line tool path


sudo xcode-select -switch /Applications/Xcode7.app 
//switch command line tool to xcode 7

sudo xcode-select -switch /Applications/Xcode.app 
//switch command line tool to xcode 8

Friday, September 23, 2016

Kerberos and NTLM authentication for ios device

Kerberos and NTLM are two authentication mechanisms used by Windows.

NTLM is Windows only, and Kerberos is RFC standard (RFC 1510), so it can be used by other platforms. NTLM is the default Windows authentication method before Windows 2000. As Kerberos has few enhancement over NTLM, so since Windows 2000, the windows client starts to use Kerberos as the preferred authentication protocol, although NTLM is still supported.

NTLM is supported by ios since iOS 2.0 (NSURLAuthenticationMethodNTLM)

Kerberos is supported by ios since iOS 7 with enterprise single sign on support.

For NTLM authentication, when client sends a request to server, if the server requires the NTLM authentication, the server will send 401 http status code to client. To handle it, the client will prompt user to input username and password, and then send back the credential information to server. Once the server gets the information it will talk to Windows Domain Controller to verify the user credential, and once verified a session cookie will return to client to indicate the authentication is succeeded. The key point is for NTLM, the web server will communicate with KDC using client provided credential to get a login token, so ios client does not need to know anything about the login secure server (KDC).

From the ios device side perspective, handling NTLM by application is no difference from handling regular 401 basic authentication. Once the challenge is received for NSURLAuthenticationMethodNTLM, then get the credential from user and send to server for authentication.

For Kerberos, the authentication is configured and handled on device level instead of application level, so once kerberos authentication is succeed, all applications installed on the device can share the authentication session with Single Sign On, so there is no need to authenticate each application separately. As for kerberos authentication, the device will directly communicate with KDC to get a login session, so the device must be configured for kerberos authentication to get the KDC information.

The main difference for Kerberos authentication is,  the device will first contact domain controller using the username and password to get a ticket from KDC (Key Distribution Center), and once the ticket is available, any application installed on the device and configured to use Kerberos can use the ticket to authenticate itself when accessing a web resource, the resource server will communicate with domain controller to verify the client side ticket. So unlike NTLM, ios application implementation are transparent to Kerberos authentication and do not need to have any logic to retrieve the user credential and send it to KDC, all it needed is to include the app id in the kerberos device profile's AppIdentifierMatches field.

Monday, September 19, 2016

Use ios cordova to load/block external content url with whitelist

For ios cordova project, since Cordova 6.0.0, (Cordova iOs 4.0.0), the function of cordova whiteplist plugin is merged into cordova core library in the source file of CDVWhiteList.m and CDVIntentAndNavigationFilter.m, so the there is no need to explicitly add the whitelist plugin into the ios cordova project.

One breaking function is when setting an external url, like https://www.google.com in config.xml's content element as below, it will not work,

    <content src="httsp://www.google.com" />

The reason is the top level url is only allow to file:// url, and it has be explicitly allowed in order to load the url. To solve the issue, add the below line to allow navigate to any url
    <allow-navigation href="*" />


The whitelist related tags in config.xml are listed below:
1.<allow-navigation> allow root webview to navigate to a particular url

2. <allow-intent> allow opening an url in inappbrowser without giving permission to load cordova plugin on the url

3. <access> allow which url the javascrpit xhr reqeust can be made to it.

In addition, the index.html created with default cordova project also have CSP (content security policy), which may limit what is able to run on the cordova page, The below is a good tutorial for the related information.
http://go.microsoft.com/fwlink/?LinkID=617697



Friday, September 16, 2016

ios auto layout settings with Hugging and Compression Resistance

Minimal auto layout settings:

For any ios view, the minimal auto layout setting is top (y) and leading space. Once these two values are decided, the auto layout can put the view in the right place.
The width and height will be decided at run time based on the view's intrinsic value. For example, if the view is UILabel, the width and height will be decided based on the label text's content along with the font selected for the label.


Optional width and height constraints:
Sometimes, it is better to fix the view's width or height regardless of the view's intrinsic content.
For example, you may want the label always use first 1/3 width of the line to align all labels on a screen. To do so, you add a proportional equal width constraint with multiplier of 0.3. Or define both leading and trailing space to decide the width based on superview's width.

Content Hugging and Compression Resistance priority 
When the width and height of the view is decided by intrinsic value, instead of fixed by constraints, then at runtime, the multiple constraints may conflict. For example, in the below


There are a leading space constraint between green label to superview, and horizontal space constrait between green label and purple label, and a trailing space constraint between purple label to superview. This works fine at design time, but at runtime, if the actual viewcontroller's width is larger or smaller than the design time viewcontroller's width, then the label view's width has to be changed to satisfy the leading and trailing space constraints. The issue is which label view should change its width?

The xcode interface build has two additional properties Hugging and Compression Resistance to control which view should shrink or expand to meet the runtime constraints requirement.

Both properties have a value of 0 to 1000, the higher the value, the higher the priority. When the size needs to be adjusted at runtime, the view who has lower hugging property value will expand its size to satisfy the constraints requirement, while the view having a higher hugging property value will keep closely hugging itself to its current size. For example, if we give green label' hugging property to 200, and purple label's hugging property to 100, then when running it on a device with bigger width, then the purple label (who has a low hugging value of 100) will grow the width to satisfy the width constraints


Similarly compression resistance property is used to decide if there are not enough width space, which view needs to shrink. The view has a low compression resistance value will shrink first. In this case, the purple label (who has low resistance property of 100) will shrink itself when running on a narrow iphone device as below. While the green label keeps its current width, who has a compression resistance property of 200.