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.