dimarts, 28 de febrer del 2017

Games, HTML5, Local Storage, Android and iOS

I'm developing what it will be my first game. It's a puzzle type game and at this moment I'm writing more levels and I hope to release it soon.

For develop the game (remember it is my first game) I decided to use HTML5 with the idea to port it to Android ans iOS easily since I only have to load the HTML into a webview and it is ready to play. Could have opted to use Cordova and so make it multi platform more easily but finally I have thought that is a little project and could implement manually the game in the two platforms and so see how it's done and see the differences between platforms.

The first consideration, is that two platforms uses WebKit so as visualize web pages, this which would lead us to think that in the two platforms will be done in the same way but exist differences.

In Android it could be something like

   public class MainActivity extends Activity {

      @Override
      protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         WebView webView = (WebView) findViewById(R.id.webView);


         webView.setWebChromeClient(new WebChromeClient());
         webView.setWebViewClient(new WebViewClient());   
         webView.getSettings().setJavaScriptEnabled(true);


         webView.loadUrl("file:///android_asset/index.html");

      }
   }

First we declare a WebView an use WebChromeClient and WebViewClient to improve the characteristics of the webview, next enable the Javascript as it is disabled by default and finally we load the page.
If as on this case the page to load is local, this must be in the directory main/assets from the project.


In iOS with Swift

   import UIKit
   import WebKit

   class ViewController: UIViewController {
      @IBOutlet weak var webView: WebView!

      override func viewDidLoad() {
         super.viewDidLoad()

         let path = NSBundle.mainBundle()
                      .pathForResource("index", ofType: "html", 
                                                inDirectory: "html")

         let requestURL = NSURL(string:path!)
         let request = NSURLRequest(URL:requestURL!)

         webView.loadRequest(request)
      }
   }

As you see it's easy too, and in this case Javascript is enabled by default. At inDirectory we have to put the name of the directory that contains the HTML in the project, in this case "html".

Well, the game is loaded and ready to play, but now, how do to save the level when the player decides to exit the game? In this case, we just want to save the level and this it's only a number and I devide to use the HTML5 Local Storage for two reasons. First it's easy from Javascript and don't require special permissions on the app. A third reason could be that is not much data to save.

To save and load the game level in the game.js file I use

   saveGame: function (level) {
      try {
         window.localStorage.level = level;
      } catch (e){
         console.log(e);
      }
   }


   loadSavedGame: function() {
      return window.localStorage.level;
   }

And now it's necessary to add a bit of code in Android and make a little change in iOS.

In Android is necessary to enable the storage in the webview. Finally the code would be like this

   public class MainActivity extends Activity {

      @Override
      protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         WebView webView = (WebView) findViewById(R.id.webView);


         webView.setWebChromeClient(new WebChromeClient());
         webView.setWebViewClient(new WebViewClient());   
         webView.getSettings().setJavaScriptEnabled(true);

         webView.getSettings().setDomStorageEnabled(true);
         webView.getSettings().setDatabaseEnabled(true);

         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            webView.getSettings().setDatabasePath("/data/data/" +
            webView.getContext().getPackageName() + "/databases/");
         }

         webView.loadUrl("file:///android_asset/index.html");

      }
   }

And in iOS we have to change the WebView to WKWebView. And the code would be like this

   import UIKit
   import WKWebKit

   class ViewController: UIViewController {
      @IBOutlet weak var webView: WKWebView!

      override func viewDidLoad() {
         super.viewDidLoad()

         let path = NSBundle.mainBundle()
                      .pathForResource("index", ofType: "html", 
                                                inDirectory: "html")

         let requestURL = NSURL(string:path!)
         let request = NSURLRequest(URL:requestURL!)

         webView.loadRequest(request)
      }
   }

WKWebView implements the necessary to work with Local Storage.

dilluns, 20 de febrer del 2017

Asynchronous task in iOS. Completion Handlers

Recently I started to develop apps for iOS, and my first step was to port an app that I have for Android. During the implementation I encountered the same problem which in Android I solved with AsyncTask, but how to solve it in iOS?

Say that the programming language used is Swift 2.0 because my system is Mavericks and last version of Xcode is the 7.2.1

Well having said that, we continue. Making a little memory, I will remember the problem. It consist in a JSON request and wait the data. For that, an easy and quickly way to do it is use completion handlers.

A completion handler is a closure and the template is as that


   {(data: NSData!, response: NSURLResponse!, error: NSError!) in 

            // code
   }

And to use it


   let task = session.dataTaskWithRequest(request: NSURLRequest, 
                completionHandler: {(data, response, error) in 
         
                //code

              })

   task.resume()       



In the body of the closure, first check if an error has ocurred

   guard error == nil else {
      print (error!)
      return
   }


Next check if we have data

   guard let jsonData = data else {
      print("Error retriving data")
      return
   }


And finally obtains the data


   do {
      let json: AnyObject = 
                  try NSJSONSerialization.
                  JSONObjectWithData(jsonData, options: .AllowFragments)

      let desc = 
          json[2]!.description.dataUsingEncoding(NSUTF8StringEncoding)

      self.description = 
          NSString(data: desc!, encoding: NSUTF8StringEncoding)

      let set = NSCharacterSet(charactersInString: "()")

      self.description = 
          self.description.stringByTrimmingCharactersInSet(set)
   } catch {
      print("Error JSON: \(error)")
   }


And to update te UI first should return to the main thread for this you can used semaphores. First we create the semaphore

   let semaphore = dispatch_semaphore_create(0)


In the body of completion handler we send the signal

   dispatch_semaphore_signal(semaphore)


And after launch the task waits for a semaphore

   dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)


Finally the function to get description look as this
   func getDescription (var name: String){
        
        name = name.stringByReplacingOccurrencesOfString(" ", 
                                                   withString: "%20")
        
        let semaphore = dispatch_semaphore_create(0)
        
        let lang: String = self.lang as! String
        let url: String = "https://" + lang + wikiURL + 
                            "?action=opensearch&search=\(name)&
                             limit=1&explaintext&format=json"
        
        
        
        let url1: NSURL = (NSURL(string: url))!
        let request: NSURLRequest = NSURLRequest(URL: url1)
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: config)
        
        let task = session.dataTaskWithRequest(request, completionHandler: 
                                        {(data, response, error) -> Void in
            
 
            //check errors
            guard error == nil else {
                print(error!)
                return
            }
            

            guard let jsonData = data else {
                print("Error retriving data")
                return
            }
            
            do {
                let json: AnyObject = try NSJSONSerialization.
                           JSONObjectWithData(jsonData, options: 
                                                .AllowFragments)

                

                let desc = json[2]!.description.
                                   dataUsingEncoding(NSUTF8StringEncoding)
                
                self.description = NSString(data: desc!, 
                                encoding: NSUTF8StringEncoding)! as String
                
                let set = NSCharacterSet(charactersInString: "()")
                self.description = self.description.
                                       stringByTrimmingCharactersInSet(set)
                

                dispatch_semaphore_signal(semaphore)
                
            } catch {
                print ("error serializing JSON: \(error)")
            }

        })
        
        task.resume()
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
       
    }


And the result looks like


dilluns, 13 de febrer del 2017

Asynchronous task in Android. AsyncTask

Continuing with asynchronous task, this time in Android.
The problem  is the same what we have in javascript or another programming language. We have to wait which a specific task ends or wait some data from a query, etc... If these task block the main thread for more of five seconds the ANR dialog is presented to de user. For that you can use threads and runs the task in background. An Android native application commonly is programming with java and the threads aren't a problem. Here can you read more about processes and threads in Android.
For facilitate the task and make it more easy is designed AsyncTask. Here can you read more about that.

Continuing with the same example used in the javascript promises entry, first we must write a class which extends AsyncTask.

   private class GetInfoTask extends AsyncTask<String, Void, String> {

   }

In an asynchronous task we use types. The first indicates the type of the parameters and it is an Array. The second, the type of the progress and it is  used for show the progress dialog and finally the type of the result. In this case, the parameters are an array of string, the progress are Void because we will use an spinner in the progress dialog and returns an string
Android Studio shows a message asking if you want to implement methods as in this image 



And if you select Implement methods the result would be like this


doInBackground is one of the four methods that we can use and it is required. This method is invoked on the background and it do the task. The rest of methods are onPreExecute() it is invoked on the UI thread and it is used for setup the task and show the progress dialog. onProgressUpdate(Progress ...) it is invoked on the UI thread and is used to display the progress. onPostExecute(Result) invoked on the UI thread when doInBackground finishes. The Result parameter is the value returned by doInBackground.
In principle it is not necessary use a constructor but if you want to show a progress dialog an application context is needed and the constructor it's a good way to pass it.

So, for our example would be

        private ProgressDialog progressDialog;
        private Context context;

        public GetInfoTask (Context context) {
            this.context = context;
        }

We first declare a ProgressDialog and a Context as global variables on the class and init the Context in the class constructor.


       @Override
       protected void onPreExecute () {
           progressDialog = new ProgressDialog(context);
           progressDialog.setCancelable(true);
           progressDialog.setMessage("Loading data...");
           progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
           progressDialog.show();
       }


In the onPreExecute we initialize the progress dialog with with the Context  and show it.

        @Override
        protected String doInBackground(String... urls) {
            String line = "";
            HttpURLConnection httpURLConnection = null;

            try {
                URL url = new URL(urls[0]);

                httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setReadTimeout(5000);
                httpURLConnection.setConnectTimeout(10000);
                httpURLConnection.setDoOutput(true);
                httpURLConnection.connect();

                BufferedReader bufferedReader =
                 new BufferedReader(new InputStreamReader(url.openStream()));
                StringBuilder stringBuilder = new StringBuilder();

                while ((line = bufferedReader.readLine()) != null) {
                    stringBuilder.append(line + "\n");
                }

                bufferedReader.close();



                return stringBuilder.toString();

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
}

doInBackground execs the task, in this case  makes a GET connection to a URL passed in the parameter urls[0] and returns a string  with the result.


        @Override
        protected void onPostExecute (String result) {
            progressDialog.dismiss();
            String data = "";

            if (result != null)
                try {
                    JSONArray jsonArray = new JSONArray(result);

                    data = jsonArray.getString(2);

                    data = data.substring(2, data.length() - 2);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                textView.setText(data);
        }

Finally in onPostExecute the result is processed, first dismiss the progress dialog and if result is not null parse the JSON Array, extract the data and show on a TextView.


In this example would be missing the progress update, which is where I would enter onProgressUpdate like


        @Override
        protected void onProgressUpdate (Integer... values) {
            super.onProgressUpdate(values);
        }
For obtain the values to update on the progress dialog use publishProgress(Progress ...) into doInBackgound.

And finally use it


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final EditText editText = (EditText) findViewById(R.id.editText);
        Button button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(R.id.textView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                GetInfoTask getInfoTask = new GetInfoTask(MainActivity.this);

                Locale locale;

                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    locale = getResources().getConfiguration()
                                          .getLocales().get(0);
                } else {
                    locale = getResources().getConfiguration().locale;
                }

                String finalUrl = "https://" + locale.getLanguage() + wikiURL
                                    + "?action=opensearch&search="
                                    + editText.getText().toString()
                                    + "&limit=10&explaintext&format=json";


                getInfoTask.execute(finalUrl);
            }
        });

First we create an object GetInfoTask and finally use it with the string containing the url getInfoTask.execute(finalUrl)

And the result can be like this

dilluns, 6 de febrer del 2017

AngularJS, $q and promises


First, to say that these entries in the blog only are a way to learn. I'm learning english for my self and I think that this is a good way to practice, so there if are some phrase poorly constructed I apologize for it.
Continuing with the asynchronous task, this time seeing as AngularJS treat the problem.
AngularJS is a javascript open source framework maintained by Google commonly used for develop single-page application. You can find more info about this technology here.

In the previous entry I commented that javascript don't use threads and who the browser only uses a thread for each page and if a task spends a lot of time it can block the browser. For solve that and not fall into callback hell, AngularJS uses the concept of promises based on Kris Kowal's Q proposal. You can find more info here.

Essentially a promise is a javascript object who in a future it will contain the value we want to return but in this moment we don't know. Each asynchronous task will return a promise and each promise have a then function with two arguments, a success handler and an error handler. The success or the error handler will be called only one time when the asynchronous task is finished. The success and error handler can return a value which will be passed to the next function in the chain of promises if exist. The then function returns a promise to allow chaining multiple calls.

A prototype can be


   method().then(function(data){
      //Manage data 
   }, function(error) {
      //Manage error
   });

And can be to chained multiple calls

   method().then(Success1, Error1)
           .then(Success2, Error2)
           .then(Success3, Error3);

For this example we are going to make a query to the wikipedia and extract a bit of info. For this, we will use the mediawiki API. You can find more info here.

For good practices, we will use the $q service from de AngularJS core and although we could use it in the controller, by good practices we will separate it creating a service.


The service it would be like this


service('fetchDataService', ['$http', '$q',function($http, $q){
   return {
      getData: function (textToSearch) {
                            
         var deferred = $q.defer();                   

         var lang = navigator.language || navigator.userLanguage;

         var wikiURL = ".wikipedia.org/w/api.php";
         var url = "https://" + lang + wikiURL + "?action=opensearch&search=" 
                       + textToSearch + "&limit=10&explaintext&format=json";
                                                 
         var result = "";

         $http.get(url).then(
            function(response) {
               result = JSON.stringify(response.data[2]);
                                    
               result = result.substring(2, result.length - 2);
               deferred.resolve(result);

             }, function(errResponse) {
                deferred.reject(errResponse.data);
             });

             return deferred.promise;                        
          }
       }                    
    }])


We first created the deferred object using the AngularJS $q object to make promises. This object will be used inside of the asynchronous call and it have two methods, resolve that we use in the success handler to which we pass the data obtained in the http get call. The second method reject is used for indicate who the request is rejected and we pass it the error as a parameter. Finally returns the promise whit the data.

Now we inject the service in the controller and use it.



controller('MainCtrl', ['fetchDataService', function(fetchDataService) {
   var self = this;
   self.text = "";
                    
   self.search = function() {
      fetchDataService.getData(self.textToSearch)
         .then(function(data) {
            self.text = data;
         }).catch(function(error) {
            self.text = error;
         });
   }
}]); 

dimecres, 1 de febrer del 2017

Javascript, Fermat's little theorem and concurrency

Javascript, Fermat’s little theorem and concurrency

Recently I encountered an article that explains the different types of primality test and one of them are the Fermat’s little theorem. It is a probabilistic test for determine if a number is prime. If the number is composed, it is true, but if it is prime, it is a probable prime as it uses a necessary condition but not sufficient for that.
For more information over this theorem can you follow this link https://en.wikipedia.org/wiki/Fermat%27s_little_theorem

A possible implementation of this algorithm in javascript could be the next

function numberPrime(num) {

   var n = 0;

   if (num <= 3) {
      return true;
   } else {
      n = Math.pow(2, num - 1);

      if (n % num == 1) {
         return true;
      } else {
         return false;
      }
   }
}



In this case only use the number 2 how testimony, that make the reliability of the test be low, but for this example it is sufficient.
If the number is composed, for show what number makes it divisible we could do it like this

function checkComposite (num) {
   var x = 2;

   while (x < num) {
      if (num % x == 0) {

         alert("It is not a prime number, " + num + " is composed for " + x + "*" + num/x);

         return;
      }
   x++;
}



 The problem is that for a number big enough this function will block the system by it test all the numbers except 1 and himself. Javascript don't use threads, the browser only uses a thread for each page and if a function spends a lot of time running, it can block the browser.

An alternative is use the library Concurrent.Thread which can be downloaded from here.
Its use is simple, the syntax is Concurrent.Thread.create(function, parameter). Continuing with the example would be

if (numberPrime(num)) {
                    
   alert("The " + num + " probably it is a prime number");
                             
} else {
                    
   Concurrent.Thread.create(checkComposite, num);

}


And the result is:



This is an example and the size of the number is limited. In another post I'll talk from the promises in AngularJS for concurrency