Hello world on HomeKit

I just setup a HomeKit apps on my home, using Apple Siri to control my television.

First, need a smart home device, for example Sony Bravia TV which connected to a home WIFI. Second, requires a HomeKit Server talking HomeKit Protocol. This server will interact with other smart home device registered as accessories. Third, requires a HomeKit client installed on mobile, which talking to HomeKit Server, adding any accessories available from HomeKit server. In usual setup, HomeKit server can installed on Raspberry PI, but I don’t have, use my Mac to host it.

The following procedures will help to setup.

1) Get a Mac with Node JS installed. Get a Apple licensed developer program.

2) Download a HomeKit Demo Swift based project, run it on your mobile. Download at https://github.com/KhaosT/HomeKit-Demo.

3) Download a HomeKit Server, I am homebridge. It is a Node.JS based server. Download at https://github.com/nfarina/homebridge.

4) Download Bravia Controlled library which is also Node.JS based. Download at https://github.com/alanreid/bravia.

5) Follow instruction on how to control Bravia TV by using the library. And then, you may build a HTTP based interface around the Bravia library. And then, you may program HomeKit server apps, add a new accessories, and then send the command requests to Bravia Server via HTTP (Turn on/off TV). The last part is much more tricky, to setup HomeKit client talks to HomeKit server.

6) Important note, once you had HomeKit client installed, navigate to one of accessories, look for the service name, this is the name Siri will look and map into. Name it as “television”, or some fancy name, which you will tell Siri to look for and do the action.

7) After that, if everything goes well, you can turn on your Siri, and say “Siri, turn on television”. Then your television magically turned on. Enjoy.

Tutorial on setup OpenCV on iOS

This tutorial is to setup OpenCV on iOS. To include opencv2.framework to iOS8 Objective C Project.

By following this tutorial: http://docs.opencv.org/doc/tutorials/ios/hello/hello.html#opencvioshelloworld

1) to download prebuilt opencv2.framework, the fine working version is 2.4.9.

2) to create new XCode Project, target iOS8.0 if you are under XCode 6.0.1 as this version not yet support iOS8.1

3) link opencv2.framework to XCode Project. Go to project build phase, and link following frameworks:
opencv2.framework
AssetsLibrary.framework
AVFoundation.framework
CoreGraphics.framework
CoreImage.framework
CoreMedia.framework
CoreVideo.framework
Foundation.framework
UIKit.framework
Accelerate.framework

Screen Shot 2015-01-20 at 12.42.28 am

4) Create <NameOfProject>-Prefix.pch, with following snippets of code add between ifdef / endif block.

#ifdef __cplusplus
#import <opencv2/opencv.hpp>
#endif

5) in ViewController.h, add the following to header
#import <opencv2/highgui/cap_ios.h>
#include <opencv2/opencv.hpp>

Note, the most important line is #include <opencv2/opencv.hpp>, this is important to make the stuffs works. I spent few hours and found this solve my problems, which unable to recognize cvtColor function, OK, will introduce in next steps.

6) To do some testing, by adding a video camera, reading 30 frames per second, process the images by inverting the color…

7) Rename ViewController.m to ViewController.mm as we are going to put C PlusPlus Code. Extension mm allows coexist of Objective C and C PlusPlus.

8) In ViewController.h, add following line
@property (nonatomic, retain) CvVideoCamera* videoCamera;

9) In ViewController.mm, we initialize videoCamera and starts it.

self.videoCamera = [[CvVideoCamera alloc] initWithParentView:_ImageView];
self.videoCamera.delegate = self;
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset352x288;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
[self.videoCamera start];

10) In ViewController.h, add CvVideoCameraDelegate

Like this

@interface ViewController : UIViewController

11) In ViewController.mm, add following snippets of code before @end.

#pragma mark – Protocol CvVideoCameraDelegate

#ifdef __cplusplus
– (void)processImage:(Mat&)image;
{
// Do some OpenCV stuff with the image
Mat image_copy;
cvtColor(image, image_copy, CV_BGRA2BGR);
bitwise_not(image_copy, image_copy);
cvtColor(image_copy, image, CV_BGR2BGRA);
}
#endif

12) Run the project. Cheers.

Photo 20-1-15 12 51 57 am

Titanium Mobile Geolocation fix after upgrading to iOS8

My Titanium Mobile apps geolocation function was broken, after deployed a release target to iOS8.

The iOS8 introduces new privacy and restriction settings. We are required to include some flags in plist settings in order to make it work.

You can open tiapp.xml, and add the following flags under ios plist dict

<key>NSLocationAlwaysUsageDescription</key>
<string>Test NSLocationAlwaysUsageDescription</string><key>NSLocationWhenInUseUsageDescription</key>
<string>Test NSLocationWhenInUseUsageDescription</string>

Save and deploy. Cheers.

Swift Tutorial to add GCDWebServer into XCode Project

GCDWebServer is a former Objective-C project that embeds a web server in iOS / OSX application. This tutorial explains how to add GCDWebServer into Swift based iOS project.

Step 1:

Navigate to empty directory, run the following

git clone https://github.com/swisspol/GCDWebServer

Step 2:

Go into GCDWebServer directory, you will see there are GCDWebServer, GCDWebDAVServer, GCDWebUploader…. In this case, we just need GCDWebServer to build a simple HTTP Server. Copy this folder to your application root folder. Looks like this.

Screen Shot 2014-12-23 at 2.20.52 pm

Step 3:

Add a bridging header if it is not exist.

Right click your project navigator, add a new “header file” under iOS source tab. Name it as <YourApplicationName>-Bridging-Header.h.

In this file, put the following


#import "GCDWebServer.h"
#import "GCDWebServerDataResponse.h"

Step 4:

Go to your project navigator, build settings, Swift compiler – Code Generation, Objective-C Bridging Header, enter the path to the <YourApplicationName>-Bridging-Header.h

Screen Shot 2014-12-23 at 2.25.47 pm

Step 5:

Go to your project navigator, build phases, under Link Binary with Libraries, click to add “libz.dylib”.

Step 6:

At the time of writing, the current GCDWebServer not working properly and have to change something make it to work.

Find GCDWebServer.h and locate addDefaultHandlerForMethod, set the second one as addDefaultAsyncHandlerForMethod.

Find GCDWebServer.m and locate addDefaultHandlerForMethod, set the second one as addDefaultAsyncHandlerForMethod. Under first addDefaultHandlerForMethod, change the second line of the occurrence to addDefaultAsyncHandlerForMethod instead.

Screen Shot 2014-12-23 at 2.33.40 pm

Step 7:

Put following test code and run.

// http server

        let webServer = GCDWebServer()

        

        webServer.addDefaultHandlerForMethod(“GET”, requestClass: GCDWebServerRequest.self) { request in

            return GCDWebServerDataResponse(HTML:“<html><body><p>Hello World</p></body></html>”)

        }

        webServer.startWithPort(8080, bonjourName: nil)

        println(“Visit \(webServer.serverURL) in your web browser”)

Step 8:

Open your desktop browser, and open the link shown in debug console. You should be able to see Hello World displayed in the web page.

Cheers.

Swift Tutorial to add library framework from Github

This tutorial explains how to add library framework from Github.

Imagine you refer to this page that having list of frameworks, and you would like to install one of the library, such as SwiftHTTP.

Step 1:

Go to the root folder of your application.

Run git submodule add <Github URL>

E.g. git submodule add https://github.com/daltoniam/SwiftHTTP

Step 2:

Open SwiftHTTP folder under the root folder of your application.

Drag SwiftHTTP.xcodeproj to your XCode Project.

Refer to below picture, drag SwiftHTTP.xcodeproj to Chats, the top level hierarchy of project.

Step 1 Drag xcodeproj to Project hierarchy

 

Step 3:

Click on SwiftHTTP.xcodeproj that added to your project hierarchy.

Check Deployment Target under General Tab.

Make sure it is the same with your application’s deployment target.

Step 3 Check Deployment Target

 

Step 4:

Click on your main application, under Build Phases Tab, click “+” under target dependencies section.

The end result is something like this.

Screen Shot 2014-12-22 at 7.53.12 pm

Step 5:

Add a new phase by clicking “+”  under Build Phases Tab, and choose “New Copy File Phase”, change the name to “Copy Frameworks”.

Screen Shot 2014-12-22 at 7.54.24 pm

Step 6:

Under the new phase “Copy Frameworks” added in last step, destination choose “Framework”, and add the frameworks.

The end result something like this

Screen Shot 2014-12-22 at 7.56.12 pm

 

Then test your code with the library:

 


var request = HTTPTask()
var params = ["k": "q:name=currency,stat=swift", "api" : "1", "server_host" : "swift"]
request.requestSerializer.headers["X-Mashape-Key"] = "Ri4j5gX4ORmshweHbjBSUUMevXWIp1i0xRujsnjCz7wW9w5zLB"
request.GET("https://imgshow-platform.p.mashape.com/", parameters: params, success: {(response: HTTPResponse) in
if let data = response.responseObject as? NSData {
let str = NSString(data: data, encoding: NSUTF8StringEncoding)
println("response: \(str)") //prints the HTML of the page
}
},failure: {(error: NSError, response: HTTPResponse?) in
println("error: \(error)")
})

 

Built custom sharer on iOS safari

I built a custom sharer module on iOS Safari. Without using iOS8 latest Action module, I used bookmark to emulate this function.

I had already sharer module in my Apps, that shows a window, enter text, embed link, and share to many social sites, such as Facebook and Twitter. I had another module so called GooGLShortenURL that can request shorten URL from goo.gl, embed in my text, share to Twitter which had character limit (140 characters).

To add the bookmark into iOS Safari, I found an intuitive way, but need Mac Apple Safari, built in iCloud works along with iOS Safari, I can then add book mark through Mac Apple Safari, edit the address bar, put in some JavaScript, and then save, and then iOS Safari will get auto synced book mark.

Screen Shot 2014-08-31 at 12.10.00 pm

The JavaScript will open my apps, using iOS Custom URL Scheme set on iPhone/build/pList file.

Screen Shot 2014-08-31 at 12.11.35 pm

I then have my code to handle incoming URL scheme request.

Screen Shot 2014-08-31 at 12.12.22 pm

In my handler, interpret the incoming URL scheme request, based on parameters, fire up Sharer module, then start sharing. I can share to many social sites just in one click.

Photo 31-8-14 12 13 35 pm

Titanium Mobile tips to get weather forecast message

This is Titanium Mobile tips to get weather forecast message, which you can use to implement in your native iOS apps.

This tutorial required Imgshow Library for Titanium Mobile hosted on Github.

We require Titanium.Geolocation method to get our current latitude and longitude, and then pass this info to API, to get weather forecast message.

The sample code to get weather forecast message:

var fetchWeather = function(cb) {
	
	Titanium.Geolocation.purpose = "Get Weather";
	Titanium.Geolocation.getCurrentPosition(function(evt) {
		
		var lat = evt.coords.latitude;
		var lng = evt.coords.longitude;
		imgshow().name('weather').p('lat', lat).p('lng', lng).p('display', 'label').load(function(data) {
			cb(data);
		});
		
	});
};
fetchWeather(function(message) {
  alert("Weather now is: " + message);
});

The sample response would be: Weather now is 28 C Mostly Cloudy at Jurong Town, Singapore.

Titanium Mobile Performance in add-removal views

In Titanium Mobile development, there is a performance penalty when trying detach or attach View object to a Windows object in the circumstances the View object containing many child objects.

Trying to implement master detail view I have a function called showItemPage() which will create a View object, and a bunch of button and label plus event listener, and attach to this View, where this view will attach into a master Window object. If there is previous other View added into Windows object, the previous view must be detached and removed before the new View can add into Windows object. The performance penalty arisen when I create the view object, and add a lot of objects inside, and then at the last attach the View into Windows object. The solution of this problem is tricky, just move “attach View into Windows object” code into the front just after you create the View, before you adding any children object into the View.

I wonder when adding the View object into a Window object, it become very slow when View object contains many child objects, but it is very fast when initially no any child objects added inside.

Side Note: to implement this I will create an object to hold the current active item view in outer context, then check every times, if the current active item view is exist, then remove that view from the Windows object, before adding the new view created to the Window object, and then set this view to current active item view.

Sample code:

if(activeItemView != null) {
	masterWin.remove(activeItemView);
	activeItemView = null;
}
activeItemView = itemView;
masterWin.add(activeItemView);

Titanium Mobile Ipad Master Detail view

It was been very easy to use Titanium Mobile to implement Master Detail view on iPad Apps.

In computer user interface design, a master–detail interface displays a master list and the details for the currently selected item. A master area can be a form, list or tree of items, and a detail area can be a form, list or tree of items typically placed either below or next to the master area. Selecting an item from the master list causes the details of that item to be populated in the detail area.

Obviously, the master-detail interface shown in iPad is the master area located at left and detail area located at right. When the functions displays on iPhone, because of the smaller screen, master view takes up full width, and then a detail item clicked, the detail view will be opened as a new window view.

The key idea to implement in Titanium Mobile concept is that:

On iPhone, we mostly creating our master view, likely a tableview, and attach with a master window (masterWindow.add(tableView)). When click into detail item, we create new item window and then open using tab controller (Ti.currentTab.open(itemWindow)). So that when user can click “Back” button from the tab bar to go back to previous view and click to open another detail view.

On iPad, after we creating our widget, we will attach the widget to a View object, which attach to the main window object (masterView = Ti.UI.createView(); window.add(masterView)). We create another detailView and attach to the main window object (detailView = Ti.UI.createView(); window.add(detailView)). We set the width of the masterView as a certain width constant, and then we adjust detailView.left attribute to the width constant, to make it stand at the right.

On iPad, to handle orientation changes, we need to also adjust the detailView.left attribute and its width in order to fits to the screen after orientation changes. The key code here:

if(Ti.Platform.osname == 'ipad') {
  descArea.width = Ti.Platform.displayCaps.platformWidth - IPAD_DOUBLEVIEW_WIDTH;
  Ti.Gesture.addEventListener('orientationchange', function(e) {
   descArea.width = Ti.Platform.displayCaps.platformWidth - IPAD_DOUBLEVIEW_WIDTH;
  });
}

Attached the example screenshots that I capture from the demo apps I implement the master-detail view on iPad using Titanium Mobile.

20140412-180654.jpg

20140412-180715.jpg

Valid Signing Identity Not Found iOS Dev problem

Had encountered problem “valid signing identity not found” during iOS Development. As my Dev Certificate had been expired.

By following Apple Provided FAQ Guide it is possible to solve this problem.

Following link: http://developer.apple.com/library/ios/#technotes/tn2250/_index.html#//apple_ref/doc/uid/DTS40009933-CH1-TROUBLESHOOTING_FAQ-WHAT_DOES__VALID_SIGNING_IDENTITY_NOT_FOUND__MEAN_AND_HOW_DO_I_RESOLVE_IT_

Can try to follow How do I delete/revoke my certificates and start over fresh? section and it should worked.