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)")
})

 

Freeswitch Outbounds call provider settings

FreeSWITCH is a scalable open source cross-platform telephony platform designed to route and interconnect popular communication protocols using audio, video, text or any other form of media.

To setup Freeswitch Outbounds call to landline or cell phone, must go through a PSTN or SIP gateway. Didlogic provides DID and SIP gateway.

This tutorial is going to configure SIP gateway on Didlogic, and configure the necessary settings in Freeswitch, in order to make outbounds call to landline or cellphone.

The step 1. Register an account on Didlogic and navigate to SIP Tab (https://didlogic.com/sipaccounts).

Create a SIP Account you will get SIP Username, Password, and you may set a caller ID from a list of DID you registered.

DIDLogic SIP Profiles

 

The step 2. You may navigate to Didlogic ‘s provided Freeswitch Configuration page (https://didlogic.com/support/setup-guides/freeswitch-config).

What we want is Freeswitch General Config


<include>
<gateway name="didlogic">
<param name="username" value="12354"/>
<param name="realm" value="sip.didlogic.net"/>
<param name="password" value="your_SIP_password"/>
<param name="register" value="true"/>
<param name="context" value="public"/>
</gateway>
</include>

Replace it with your SIP account username, and password created in Didlogic SIP Accounts Page.

The step 3. Go to your Freeswitch installation directory, for example, installed in a Linux box the location will be: /usr/local/freeswitch/conf/sip_profiles/external

Vi didlogic.xml, and paste the contents above, and :wq! to save the file.

If your Freeswitch is open and running, go to /usr/local/freeswitch/bin/fs_cli, then type reloadxml, it will reload the xml configuration.

Now, you can make a test call.

The step 4. You may go to /usr/local/freeswitch/bin/fs_cli, type:

originate sofia/gateway/didlogic/65xxxxxxxx ''

Then your phone will get the call. You will see the caller id is the same you defined at Didlogic SIP Profiles page.

For advanced Caller ID settings in Freeswitch, I not tried, you need have a verified business custoemr in Didlogic, then you can follow this tutorial https://didlogic.com/support/setup-guides/freeswitch-own-cli, then you may be able to configure your custom CLI.

JavaScript inet_aton functions comparison

I came across this stun.js code and found one interesting implementation of inet_aton functions. I curious of its formula and equation.

function inet_aton(a) {
    var d = a.split('.');
    return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}

I written a simple Node.JS test script just to evaluate, calculate different implementations of inet_aton, and here is my findings:

function inet_aton(a) {
    var d = a.split('.');
    return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}
function inet_aton_b(ip){
    var a = new Array();
    a = ip.split('.');
    return((a[0] < < 24) >>> 0)  + ((a[1] < < 16) >>> 0) + ((a[2] < < 8) >>> 0) + (a[3] >>> 0);
}

function inet_aton_c(a) {
   var d = a.split('.');
   return d[0] * 256 * 256 * 256 + d[1] * 256 * 256 + d[2] * 256 + d[3];
}

var start;
start = new Date().getTime();
for(var i = 0; i < 1000000; i++) {
inet_aton('1.1.1.1')
}
console.log('elapsed:' + (new Date().getTime() - start));


start = new Date().getTime();
for(var i = 0; i < 1000000; i++) {
inet_aton_b('1.1.1.1')
}
console.log('elapsed:' + (new Date().getTime() - start));

start = new Date().getTime();
for(var i = 0; i < 1000000; i++) {
inet_aton_c('1.1.1.1')
}
console.log('elapsed:' + (new Date().getTime() - start));

See the first implementation run faster. The key point is lesser multiplication is performed, by factoring using simple math.

I run the same code on Java but I found different things, I can't tell which one run faster than other one. If I run the first code first, second code followed, always the second block faster than first block. If I exchange, run second code first, first code followed, always the second block faster than first block. They both run in same speed. I even use javap to view its bytecode and found second code have more instruction than first one, but might be JVM can do its optimization so that end result both code run same speed.

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

Java/JavaScript Tips on Append to File

This is Java/JavaScript Tips on Append content to file. I will introduce append file via command line, Java, and Node.JS (JavaScript).

To append file via command line, in Windows or Unix, you can do:

echo "test" >> a.txt

The file a.txt will be created if not exist at the first time. And the subsequence calls of >> will append the content to next line of the end of file.

To append file via Java, you can do:

PrintWriter pw = new PrintWriter(new FileWriter(new File("a.txt"), true)); 
pw.println("test");
pw.close();

The file a.txt will be created if not exist at the first time. And the subsequence calls of PrintWriter.println will append the content to next line of the end of file.

The interesting thing is I like to use PrintWriter, to call println, which I not need to append \n myself.

Notice the true variable at new FileWriter, this let Java know you want to append file, if you not provide this variable, Java will always overwrite the file but not appending.

To append file via JavaScript, you can do:

in asynchronous calls:

var fs = require('fs');
fs.appendFile('a.txt', 'content\n', function(err) {
 // some callback after append file
});

OR

in synchronize calls:

var fs = require('fs');
fs.appendFileSync('a.txt', 'content\n');

The file a.txt will be created if not exist at the first time. And the subsequence calls of appendFile or appendFileSync will append the content to next line of the end of file.

Node.JS provides asynchronous and synchronize versions for each File IO Calls. Refer the link here. Other than appendFile, for example, readFile/readFileSync, writeFile/writeFileSync.

Node.JS itself is a single threaded and asynchronous. It is always recommended to use asynchronous version of method instead of synchronize version, as synchronize version is a blocking calls. If the content need append to file is very very big, the calls will just hang there, Node.JS cannot handle other requests anymore. To learn how Node.JS back end works, refer here.

Java tips String concatenations using StringBuffer

Java provides StringBuffer and String. Always use StringBuffer when you want concatenate string. StringBuffer has better performance over String when doing simple string concatenation.

String is immutable, that something cannot be changed. When you concatenate using String, JVM actually create new Object for each concatenation. Create new Object is expensive. See below example.

When using String, you may doing something like:

String message = ""; // new object
message = message + "I am "; // another new
message = message + "25"; // another new
message = message + " years old"; // another new

When using StringBuffer, you will doing something like

StringBuffer sb = new StringBuffer(); // new object here
sb.append("I am ");
sb.append("25");
sb.append(" years old");
String message = sb.toString(); // another new

As you can see, by using String, you create a bunch of new objects. When you have more things to concatenate, more and more objects created, and again, creating new object is very expensive, and make application performance worse.

It is strongly recommended by using StringBuffer to append string, and at the last, call toString() to export the string content into String object, then you can use it for any purpose.

So for the example on Java tips on joining string with separator, the code can be changed to below:

private static String join_1(String[] array, String separator) {
	StringBuffer sb = new StringBuffer();
	String comma = "";
	for(int i = 0; i < array.length; i++) {
		sb.append(comma + array[i]);
		comma = separator;
	}
	return sb.toString();
}

private static String join_2(String[] array, String separator) {
        StringBuffer sb = new StringBuffer();
	for(int i = 0; i < array.length; i++) {
		sb.append(array[i] + separator);
	}
        String s = sb.toString();
	return s.substring(0, s.length() - separator.length());
}

Another note, when use String for concatenation, internally it will create StringBuffer to do actual concatenation. Refer this link for more information.

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.

JavaScript Tips on Objects and Array and their For loop

This is JavaScript Tips on Objects and Array and their For loop.

In JavaScript, there is an Object and represented as:


var someObj = {name:"YongHao", age:25}

There is an Array and represented as:


var someArr = [1,2,3,4]

Use normal for loop only for Array, and use for…in only for Object.

For example, for Object

var someObj = {name:"YongHao", age:25}
for(var i in someObj) {
  console.log(i + ' - ' + someObj[i]);
}

We get:
name – YongHao
age – 25

For Array

var someArr = [1,2,3,4]
for(var i = 0; i < someArr.length; i++) {
  console.log(i + ' - ' + someArr[i]);
}

We get:
0 - 1
1 - 2
2 - 3
3 - 4

Do not use for...in to Array, if you do:

var someArr = [1,2,3,4]
for(var i in someArr) {
  console.log(i + ' - ' + someArr[i]);
}

It may return good result, but not recommended, as i now is a string but not an integer.