iOS 10 and Privacy Settings — July 8, 2016

iOS 10 and Privacy Settings

In iOS 10, Apple has updated the scope of privacy controls to the user’s music library such as Siri and Speech Recognition.

Another significant change is iOS 10 is that we must declare “Privacy” settings to access to private data otherwise our App will crash.

Once you link with iOS 10 you must declare access to any user private data types. You do this by adding a usage key to your app’s Info.plist together with a purpose string. The list of frameworks that count as private data is a long one:

Photos, Camera, Location,Contacts, Calendar, Reminders, Bluetooth Sharing, Microphone, Health, HomeKit, Media Library, Motion, CallKit, Speech Recognition, SiriKit, TV Provider.

If you are using one of these frameworks and fail to declare the usage your app will crash when it first makes the access. The crash log helpfully tells you which key you are missing. For example, this is the result of accessing the camera without adding the key to Info.plist:

This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

To avoid the crash we need to add the suggested key to ‘Info.plist’ (Xcode 8 already contains the full list of possible keys): Select Privacy – Photo Library Usage… from the menu.

Privacy

If you wish to add this directly to XML, the key/value is this:

<key>NSPhotoLibraryUsageDescription</key>
<string>Set the Background</string>

The system shows the purpose string when asking the user to allow access (so you may want to localize it):

Access

Major point I need to clarify is that accessing location service without a purpose string app is not getting crashed as it did with Photo Library or Camera. If our app is trying to access private data without mentioning purpose string you expect your App to crash.

iOS 10 and UIViewPropertyAnimator — July 4, 2016

iOS 10 and UIViewPropertyAnimator

In iOS 10 you can easily make any UIKit animation user-driven using UIViewPropertyAnimator. That means you can now finally replicate that effect Springboard does when you pull down Spotlight’s search bar and it gradually blurs as you get it closer to its final position. It’s the very effect that was mentioned as an example of what we could do with blur radius animations when they were announced.

Here’s an example of how to do an interactive blur. It’s driven by a UISlider just to keep it short, but it’s easy to drive the same thing with gesture recognizer, scroll view delegate or anything else you can imagine.

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var blurEffectView: UIVisualEffectView!
var propertyAnimator: UIViewPropertyAnimator?

override func viewDidLoad() {
        super.viewDidLoad()

        propertyAnimator = UIViewPropertyAnimator(duration: 1, curve: .linear) {
            self.blurEffectView.effect = nil
        }
    }
    @IBAction func sliderValueChanged(_ sender: UISlider) {
        propertyAnimator?.fractionComplete = CGFloat(sender.value)
    }
}

You will get below output after running above code. Please set image as per your choice:

BlurImage

Xcode 8 – Automatic Code Signing —

Xcode 8 – Automatic Code Signing

Xcode 8 has new feature called “Automatic Code Signing”. The CODE_SIGN_IDENTITY and PROVISIONING_PROFILE setting were hard to get to and not directly linked to each other. Most of the developer has gone through errors like “No Matching Provisioning Profiles Found” or “The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile.”.

But new Xcode 8 is completely rebuilt provisioning system should address all of this.Now we have choice how we can code sign and provision our apps. Instead of Build Settings, Code Signing is now displayed in the General tab.

CodeSign1
General Tab – Automatic Code Siging
CodeSign2
General Tab – Manual Code Signing

When “Automatically manage signing” is unchecked we can specifically select the provisioning profile we wish to use for each Configuration. Now this in itself is nothing new, we have always been able to do this in the Build Settings tab. The awesome sauce comes in with the smarts that Xcode 8 displays here. The drop down list of profiles now groups the Eligible profiles above the Ineligible profiles. Meaning that profiles that match the bundle identifier absolutely or with a wild card will be displayed above any profiles that don’t match at all.

Not only that, if you select a profile that doesn’t match the bundle identifier you now get error messages that will tell you exactly what the problem is.

This is a massive improvement over what we had in the past. No longer is Xcode hiding the details from us. No longer should we have to hunt and peck to find out what might be wrong. Xcode 8 will tell you exactly what is wrong, misaligned, expired, or missing. If we stopped right there I would be completely satisfied with the code signing changes. I know I sound like an infomercial but, it get’s better!

Automatic Code Signing is what many people are excited about.It looks great and it will probable be used by a ton of developers.

Carthage – iOS Dependancy Manager — June 28, 2016

Carthage – iOS Dependancy Manager

CocoaPods are extensively wonderful but there is another option as well. Carthage is one of them for any cocoa application either iOS or Mac. It is tremendously easy to use compare to CocoaPods. It is developed by group of developers from Github. What I most like about it is – It is the first dependancy manager to work with Swift; and It is developed in Swift Language. We all know Apple has already started emphasis towards Swift so It will be better to get to know about Carthage.

1. Install Carthage in your computer

Download latest version from https://github.com/Carthage/Carthage/releases. Double-click Carthage.pkg to run the installer. Click Continue, select a location to install to, then click Continue again, and finally click Install.

You can also use Homebrew and install it simply by running brew update and brew install carthage.

Run carthage version command to ensure, it is perfectly installed on your system or not. It will display like 0.16.2.

2. Create Cartfile in your project directory

Run below commands :

cd ~/Path/Project

touch Cartfile

open -a Xcode Cartfile

github “Alamofire/Alamofire” == 2.0

github “SwiftyJSON/SwiftyJSON” ~> 2.3.0

3. Build Dependancy

Run below command to create required framework into your project directory.

carthage update –platform iOS

For more help on update command, use carthage help update for details.

4. Add Frameworks to your project

By default, Carthage will perform its checkouts and builds in a new directory named Carthage in the same location as your Cartfile. Open up this directory now by running:

open Carthage

You should see a Finder window pop up that contains two directories: Build and Checkouts. Take a moment to see what Carthage created for you.

Select the Project’s target, choose the General tab at the top, and scroll down to the Linked Frameworks and Libraries section at the bottom.

In the Carthage Finder window, navigate into Build\iOS. Now, drag both Alamofire.framework andSwiftyJSON.framework into the Linked Frameworks and Libraries section in Xcode.

Next, switch over to Build Phases and add a new Run Script build phase. Add the following command:

/usr/local/bin/carthage copyframeworks

Click the + under Input Files and add an entry for each framework:

$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework 

$(SRCROOT)/Carthage/Build/iOS/SwiftyJSON.framework

Strictly speaking, this build phase isn’t required for your project to run. However, it’s a slick workaround for an App Store submission bug where apps with frameworks that contain binary images for the iOS simulator are automatically rejected.

Congratulations, you’ve learnt about the philosophy behind dependency management and behind Carthage itself, gained some experience using Carthage to add some dependencies to a project, and used those dependencies to make a useful app!

You also know how to update your dependencies for future releases.

If you want to learn more about Carthage, your first stop should be the Carthage README and the documentation on Build Artifacts.

Physical Web Link — June 10, 2016

Physical Web Link

The Physical Web is a discovery service; a smart object (beacons) broadcasts relevant URLs that any nearby device can receive.

Google’s approach is to scrap the app altogether and return to the fundamental building block of the traditional web: the URL.

Physical Web is just like an extension of web.

Google’s Physical web suggests URLs not the apps.

Your browser will display URLs representing the beacon-style broadcasts of nearby smart objects, and rank them like search results by some combination of proximity, signal strength, user preferences and browsing history.

Google’s Eddystone protocol supports broadcasting URLs in BTLE advertisement packets via its Eddystone-URL frame type.

In order to get up and running we need two things:

  1. A hardware beacon (or two) that supports Eddystone-URL advertisement packets.
  2. App or Chrome browser on your phone/tablet to scan for Eddystone-URL advertisement packets.

Here is the actual working flow:

Screen Shot 2016-06-10 at 12.45.57 PM

Here is the various use cases belongs to this technology :

Static Information Page :

The beacon broadcasts a URL that points to a page with relevant information.

Active Web Server :

The beacon broadcasts a URL of a web app that uses more advanced web technologies to other interactive experiences. Some examples are:

1. Push Notification using Web App

The beacon broadcasts the URL of a webpage that implements a Service Worker with push notifications.

Demo how it works: https://youtu.be/b0GDk-53fTo

2. Parking Meter using Web Socket

The parking meter has a radio antennae providing Internet access. The beacon within points to a webpage (with the meter’s ID encoded in the URL) that uses web sockets to connect to the parking meter. From this webpage, the user can easily use credit card auto fill or other online payment APIs to add time to the meter.

Demo how it works: https://youtu.be/ysxB_PXFImE

Web Bluetooth :

A standardized open web JavaScript Bluetooth API is currently in the works. This API will allow webpages to directly connect to nearby Bluetooth devices.

Web Bluetooth enables devices to offer advanced interactions without requiring a connection to the Internet. For example, the parking meter from the active web server section above could be implemented with only a direct Bluetooth connection and with no Internet connection of its own. A direct Bluetooth connection can also be much faster than passing interaction through the cloud, since network latency is avoided. Not to mention, a Bluetooth antenna is much cheaper than providing internet-connectivity, enabling more ubiquitous interactivity in everyday devices:

Happy Meal Toy Examples:

The toy broadcasts a URL to a webpage that contains JavaScript to directly connect to the toy via Bluetooth. The toy is a standalone device that can be played with by youngsters, while the webpage interaction lets the parent easily configure and personalize the toy.

Demo how it works: https://youtu.be/PwK3ccOJ6EY

Physical Web Beacon Demo App:

You can download below apps in iOS/Android to see how it will work.

iOS – https://itunes.apple.com/us/app/physical-web/id927653608?mt=8#

Android – https://play.google.com/store/apps/details?id=physical_web.org.physicalweb

The app is having 4 sample beacons for all users. We do not have any beacon so it will be easy to see the functionality.

References:

https://google.github.io/physical-web/

http://beekn.net/2015/07/google-eddystone-jumps-browser-ios/

http://postscapes.com/googles-physical-web-suggests-urls-not-apps-are-the-future-of-the-internet-of-things

http://beekn.net/2015/07/google-updates-terms-service-physical-web/

https://github.com/google/eddystone

 https://github.com/google/eddystone/blob/master/protocol-specification.md

 https://twocanoes.zendesk.com/hc/en-us/articles/203989519-Physical-Web-    Beacon-Setup

 

WKWebView to handle Social Logins like Facebook, LinkedIn and Google — June 1, 2016

WKWebView to handle Social Logins like Facebook, LinkedIn and Google

Recently, I have faced one problem while opening sign up/sign in page from web page within iOS app. We have used UIWebView earlier but we were unable to achieve so we have tried WKWebView. I am just describing what steps we have followed to achieve our goal.

First of all, we need to import WebKit framework in class where we want to use it.

#import <WebKit/WebKit.h>

Add various delegates which are required to receive various navigation events and errors.

@interface ViewController : UIViewController <WKNavigationDelegate,
WKUIDelegate,WKScriptMessageHandler>

WKNavigationDelegate -> This protocol can provide methods for tracking progress for main frame navigations and for deciding  policy for  main frame and subframe navigations.

WKUIDelegate -> This protocol provides methods for  presenting native UI on behalf of a web page.

WKScriptMessageHandler -> This protocol provides a  method for receiving messages from JavaScript running in a web page.

Since WKWebView doesn’t yet show up as drag and droppable view in storyboard or Interface builder so we need to create WKWebView Instance programmatically and add it in view.

Create two properties to load web pages one for main web page URL and another is for pop up window for Facebook, LinkedIn or Google sign in page.

@property (strong,nonatomic) WKWebView *webView;
@property (strong,nonatomic) WKWebView *popWindow;

Put below source code in your viewDidLoad.

NSURL *url = [NSURL URLWithString:@"http://your web page"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
WKPreferences *thisPref = [[WKPreferences alloc] init];
thisPref.javaScriptCanOpenWindowsAutomatically = YES;
thisPref.javaScriptEnabled = YES;
theConfiguration.preferences = thisPref;
_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:theConfiguration];
[_webView loadRequest:request];
[_webView setBackgroundColor:[UIColor clearColor]];
[self.view setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:_webView];

Below function helps to create WKWebView pop up or new window for social logins.

-(WKWebView *) getPopwindow:(WKWebViewConfiguration*) configuration{
WKWebView* webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
webView.frame = CGRectMake(self.view.frame.origin.x,self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
return webView;
}

This function helps to dismiss or remove pop up window.

-(void) dismissPopWindow:(WKWebView*) webView{
    NSString *url = webView.URL.host.lowercaseString;
    if ((_popWindow != nil && [url containsString:HostPrefix]) || (_popWindow != nil && [url containsString:LINKEDIN_HOST])){
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (_popWindow != nil){
                [_popWindow removeFromSuperview];
                _popWindow = nil;
            }
        });
    }
}

Now add various delegates methods or message handlers. Communication from web to app has improved significantly with these message handlers.

# pragma mark WKUIDelegate
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
    _popWindow = [self getPopwindow:configuration];// It will open new window
    _popWindow.navigationDelegate = self;
    [self.view addSubview:_popWindow];
    return _popWindow;
}

#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSLog(@"%@", message);
}

#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"%s", __FUNCTION__);
}
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    NSLog(@"%s", __FUNCTION__);
    // You can inject java script here if required as below
    //NSString *javascript = @"var meta = document.createElement('meta');meta.setAttribute('name', 'viewport');meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');document.getElementsByTagName('head')[0].appendChild(meta);";
    //[webView evaluateJavaScript:javascript completionHandler:nil];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    NSLog(@"%s", __FUNCTION__);
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    NSLog(@"%s", __FUNCTION__);
    [[[UIAlertView alloc] initWithTitle:@"Network Error"
                          message:NWServerErrorMessage
                          delegate:nil
                          cancelButtonTitle:NSLocalizedString(@"OK", nil)
                          otherButtonTitles:nil, nil] show];
}
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"%s", __FUNCTION__);
    NSLog(@"%@",webView.URL.absoluteString.lowercaseString);
    [self dismissPopWindow:webView];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    [self dismissPopWindow:webView];
    decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    decisionHandler(WKNavigationResponsePolicyAllow);
}

Just run the app and you will get the expected outcome.

WKWebView inherits much of the same programming interface as UIWebVIew, making it convenient for apps to WKWebKit. Only one condition, WebKit has support for iOS 8 and above.

WKWebView has higher performance compared to UIWebView. WKWebView API has the same performance as Safari App, which has the Nitro JavaScript Engine.