Saturday, May 30, 2015

Swift syntax for closure and generic alertbox function

Closure in swift is corresponding to block in Objective C, but its syntax is quite different from block in objective C, or other languages. One thing to notice is closure syntax in swift is quite similar to function definition, but without parameter name.

For example, the beginBackgroundTaskWithName defined in UIApplication class has closure parameter handler as shown below, which takes no parameter () and return Void. In addition, the closure can be nil indicated by the optional type flag ?.

func beginBackgroundTaskWithName(_ taskName: String?,
               expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier

A sample code to call the method may looks like:
    var bgTask :UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
     bgTask = application.beginBackgroundTaskWithName("logout", expirationHandler: { () in
            ...
            application.endBackgroundTask(bgTask)
            bgTask = UIBackgroundTaskInvalid;
     });

Now, let take UIAlertAction as a sample to create a generic alertbox. The constructor of UIAlertAction takes a closure parameter handler, which takes a UIAlertAction parameter and return Void. the handler is not optional indicated by !
UIAlertAction(title title: Stringstyle style: UIAlertActionStylehandler handler: ((UIAlertAction!) -> Void )!)

Let see how to create a generic alertbox that takes a title, message, buttonTitle and handler parameters, and once ok is clicked, it will call the handler parameter passed to it

func alert(title: String, message: String, buttonTitle: String, handler:((UIAlertAction!) -> Void )!){             var alertDlg : UIAlertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
    
        var okAction : UIAlertAction = UIAlertAction(title: buttonTitle, style: UIAlertActionStyle.Default, handler:handler);
                    
         alertDlg.addAction(okAction)
         self.presentViewController(alertDlg, animated: false, completion: nil)
 }

A sample code to call the method looks like
self.alert("Warning", message: "The passcode is not correct, please try again", buttonTitle: "Ok",            handler: {(alert) in    println("ok pressed")})


Thursday, May 14, 2015

Debug the first line of js code when page loads

Similar to debug cordova app when app starts, the similar approach can also be used to debug general javascript html page. 

Assume when page starts, it runs the below method, and you need to attach debugger on it.
       
var startFunc = function(){
           console.log("my start func");
}

startFunc();


Then adding the delayedStartForDebug method and also call  delayedStartForDebug(startFunc); will give you enough time to attach the debugger

var startFunc = function(){
           console.log("my start func");
}

var delayedStartForDebug = function(func) {
        var originThis = this;
        var bWait = true;
        var bDone =false;
        var i = 0
        var timer = setInterval(
                function(){
                    if (bWait && i < 10 ){
                        i++;
                        console.log("set bWait to false from console window to continue");
                    }
                    else{
                        if (!bDone){
                            bDone = true;
                            clearInterval(timer);
                            func.apply(originThis, arguments);
                        }
                    }
             }, 3000);
   }
   
   //startFunc();

   delayedStartForDebug(startFunc);

Thursday, May 7, 2015

Beautify javascript file with npm js-beautify

npm package can be used to beautify the javascript file for easy read and debug.

To do so, first download js-beautify package by run:
npm -g install js-beautify

then run the follow command to beautify it
js-beautify oldfile.js -o newfile.js

The new file will be beautified with proper indent.

If you use xcode for most of your work, then it is a good idea to install the xcode plugin for js-beautify. The detailed information is available at
https://github.com/bumaociyuan/JSFormatter-Xcode

oAuth and SMAL authentication

SAML and oAuth are two popular authentication methods used in web application, but they are for different purposes.

SAML is more similar to other authentication methods, such as basic, client cert, etc., in which, the web server must manage user's authorization information, and decide which user can perform what kind of operation. The major benefit of SAML over other authentication methods are Single-Sign-On, so that a independent identity provider can handle authentication request for multiple service providers. The key thing is although different service providers cannot share their authentication session with each other, the authentication session in the common identity provider can be used by all service providers, so as long as user has a valid authentication session on the SAML identity provider, then multiple service provider can reuse it without requiring user to authenticate again.

oAuth, on other hand, is quite different. When a web server uses oAuth, it no longer manager each user or user group's information, instead, it relies on the oauth provider's instruction on what operation can be performed on a oauth session. The oauth provider will authenticate the user and also authorization user' permission. As web server no longer manages user's information, so it does not need to expose the user credential to web server. Note oauth provider still needs to authenticate the user, using SAML, Basic, or client certificate. So it moves both authentication and authorization task out of the web server to third party oauth provider.

When oauth provider returns an oauth access token to web server, the web server must decide whether to allow the session to access the required web resource, this means there is a close coupling between the oauth authorization provider and web server. That is why, usually oauth provider from one company only support the web service from the same company. While on the other hand, SAML provider from one company can be easily used in other company's web service.

As oAuth can use SAML for user authentication, so SSO benefit from SAML authentication can also be used by oAuth. If user is already authenticated with the SAML IDP, the SAML session can also be used by any SAML service provider powered oauth web server, so the oauth provider can directly return an access token without requiring user to input his credential on the oAuth login page. 

Wednesday, May 6, 2015

Understanding promise in javascript

Please reference https://promisesaplus.com/ for promise specification.

Usually for aync js request, onSuccess and onError callback parameter are required to handle the async result. Those callback parameters must be passed in when calling the async method as below in the callMyTask function.

function myAsyncTask(onSuccess, onError) {
   setTimeout(function(){
            i++;
            if (i < 3){
                onSuccess(i); 
            } else {
               onError("i is larger than 3"); 
            }
    }, 3000);
}

function callMyAsyncTask(){
    myAsyncTask(
       function(i){
           console.log("result is: "+ i);
       },
       function(error){
          console.log(error);
       });
}
Sometimes the callback method will invoke another async request, needs to provide another set of onSuccess and onError callback methods. And those nested callback methods all need to be provided when making the initial async request, and this makes the code hard to read and maintain


Promise can be used to solve the issue. The key difference between promise and tradition way of async method is, when using promise to invoke an async request, it does not need to provide the callback method immediately. Instead, the callback methods are provided on the returned promise object using then method. As showing in the below sample when calling myAsyncTaskWithPromise() within callAsyncTaskWithPromise method, there is no callback provided, the callback is specified later using then method, this looks like a synchronized request.


function myAsyncTaskWithPromise(){
     var promise = new Promise(function(resolve, reject) {
            
         setTimeout(function(){
            i++;
            if (i < 10){
                resolve(i); // we got data here, so resolve the Promise
            } else {
               reject(Error("i is larger thatn 3")); //reject
            }
         }, 3000);
          
      });
      return promise;

}

function callAsyncTaskWithPromise() {
      var prom = myAsyncTaskWithPromise();
      prom.then(function(data) {
            console.log('Promise fulfilled of larger than 10');
          },
          function(error) {
             console.log('Promise rejected.'+ error);
      });
}

More important, the then method must also return another promise, and then method can be called on this returned promise again to provide success and error callback function.

If then's success or error callback method returns a value, or an object, or void (i.e. not having a return value),  which is not a promise, then the returned value will be wrapped as a new premise, and immediately pass the new fulfilled promise to the chained next then method's success or error callback method.

However, if then's success or error callback returns a new promise,  the chained then's resolution methods will be delayed until the new promise is fulfilled or rejected later.


The then method can be chained as shown in the below sample on nestedProm object. The sample returns a new promise from the first promise's callback method.


function myNestedAsyncTaskWithPromise(){
     var promise = new Promise(function(resolve, reject) {
            
         setTimeout(function(){
            i++;
            if (i < 10){
                resolve(i); // we got data here, so resolve the Promise
            } else {
               reject(Error("i is larger than 10")); //reject
            }
         }, 3000);
          
      });
      return promise;

}

function callNestedAsyncTaskWithPromise() {
      var prom = myAsyncTaskWithPromise();

      var nestedProm = prom.then(function(data) {
            console.log("outer then callback called");
            return new Promise(function(resolve, reject){
                setTimeout(function(){
                     if (data <5){
                           resolve(data);
                     }
                     else{
                          reject(Error("data is large  than 5"));
                     }
                  }, 3000);
              });
          },
          function(error) {
             console.log('Outer promise rejected.'+ error);
      });

      nestedProm.then (function(data){
                 console.log('Nested promise fulfilled of larger than 5');
            },
            function(error){
                  console.log('Nested promise rejected.'+ error);
            });

}    

The whole html file are attached below

<!DOCTYPE HTML>

<html>

<head>

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<meta charset="UTF-8" />


<title>javascript test</title>
<script type="text/javascript" >
var i =0;

function myAsyncTask(onSuccess, onError) {
   setTimeout(function(){
            i++;
            if (i < 3){
                onSuccess(i); 
            } else {
               onError("i is larger than 3"); 
            }
    }, 3000);
}

function callMyAsyncTask(){
    myAsyncTask(
       function(i){
           console.log("result is: "+ i);
       },
       function(error){
          console.log(error);
       });
}

function myAsyncTaskWithPromise(){
     var promise = new Promise(function(resolve, reject) {
            
         setTimeout(function(){
            i++;
            if (i < 10){
                resolve(i); // we got data here, so resolve the Promise
            } else {
               reject(Error("i is larger thatn 3")); //reject
            }
         }, 3000);
          
      });
      return promise;

}

function callAsyncTaskWithPromise() {
      var prom = myAsyncTaskWithPromise();
      prom.then(function(data) {
            console.log('Promise fulfilled of larger than 10');
          },
          function(error) {
             console.log('Promise rejected.'+ error);
      });
}

function myNestedAsyncTaskWithPromise(){
     var promise = new Promise(function(resolve, reject) {
            
         setTimeout(function(){
            i++;
            if (i < 10){
                resolve(i); // we got data here, so resolve the Promise
            } else {
               reject(Error("i is larger than 10")); //reject
            }
         }, 3000);
          
      });
      return promise;

}

function callNestedAsyncTaskWithPromise() {
      var prom = myAsyncTaskWithPromise();

      var nestedProm = prom.then(function(data) {
            console.log("outer then callback called");
            return new Promise(function(resolve, reject){
                setTimeout(function(){
                     if (data <5){
                           resolve(data);
                     }
                     else{
                          reject(Error("data is large  than 5"));
                     }
                  }, 3000);
              });
          },
          function(error) {
             console.log('Outer promise rejected.'+ error);
      });

      nestedProm.then (function(data){
                 console.log('Nested promise fulfilled of larger than 5');
            },
            function(error){
                  console.log('Nested promise rejected.'+ error);
            });
}    

</script>
</head>

<body>
    <button id="test" onclick="callMyAsyncTask()">asyncTask</button>&nbsp;&nbsp;
    <button id="asyncpromist" onclick="callAsyncTaskWithPromise()">asyncpromist</button>&nbsp;&nbsp;
    <button id="asyncpromistNested" onclick="callNestedAsyncTaskWithPromise()">nestedasyncpromist</button>&nbsp;&nbsp;

</body>

</html>

Tuesday, May 5, 2015

Using hidden button to trigger segue action for ios screen navigation

When handling ios screen navigation in storyboard, segue is very easy to define how the navigation and unwinding happens. However, navigation with segue requires an UI element (such as a button or a tableviewCell item) on the view so we can drag and drop from it to the destination viewcontroller, and the issue is, quite often there is not an element in UI to trigger the navigation, and the navigation is triggered by other logic conditions.

In order to still use the segue to configure the navigation and unwinding, an easy way is creating a hidden button in the source viewcontroller, and then creating a segue by dragging and dropping from the hidden button to the destination viewcontroller. Then in the code, when the navigation is required, just programmatically call button onclicked event or performSegueWithIdentity method to start the navigation.

The similar way can be used to unwind to the previous viewcontroller, just creating a hidden button on the current view controller and then associate it with the current viewcontroller's exit delegate, and then select an winding action method from the previous viewcontroller.

One benefit of this approach is easy to test, you can always show the hidden button and click it to see whether the screen navigation works. Once it works, then hiding it and programmatically trigger the segue based on the application logic.