Thursday, March 31, 2016

Android Implementing searching

Android provides either a search Dialog that appears on top of the activity window or a search widget that one can insert in the layout. Both search dialog and search widget can deliver the user’s search query to a specific activity in the application. Some of the features readily available in the search dialog and widget include Voice search, Search suggestions and recent queries, search suggestions that matches actual result in the application data. 

Search dialog UI appears on top of the activity upon activating it. this component can also deliver search suggestions. 
Search widget is an instance of SearchView that can be placed anywhere in the app layout. 

When user executes a search from the search dialog or search widget, the system creates an Intent and stores the user query in it. The system then starts the activity that application has declared to handle the searches and delivers the Intent. Below are the items required to set up application as assisted search. 

A searchable configuration: An XML file that configures some settings for the search dialog or widget. It includes settings for features such as voice search, search suggestion and hint text for the search box. 

A searchable Activity : The Activity that receives search query. Searches the data and displays the search results. 

A search interface, provided by either 
- The search dialog -> Search dialog is hidden by default, and it appears when calling onSearchRequested. 
- A SearchView widget -> allows to put a search view anywhere in the activity. 

For creating search configuration, app needs to have searchable.xml under res/xml folder. Below is the XML for searchable configuration

?xml version="1.0" encoding="utf-8"?
searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_label"
android:hint="@string/search_hint" 
/searchable

label is the only required attribute, which should be attribute name. The label is shown only when user activate the searchable suggestions. 

A searchable Activity can be created by declaring searchable activity in the manifest file. After doing this, whenever user searches within a dialog or search widget, the system starts the application searchable activity and delivers the search query in an Intnet with ACTION_SEARCH. The intent has Query extra using which the data can be retrieved. Below is how we can declare the activity as a searchable one

application ... 
activity android:name=".SearchableActivity" 
intent-filter
action android:name="android.intent.action.SEARCH"
/intent-filter
meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"
/activity
...
/application


references:

What is firebase?

This is a service to provide apps backend including data storage, user authentication, static hosting etc.


Firebase stores the data in JSON format and synchronises the data between apps in multiple platforms.
Based on the volume of users in the app, it automatically scales up. Data is transferred over a secure SSL connection with a 2048 bit certificate. Database access and validation is controlled at a granular level using flexible security language. All of the data security logic is centralized in one place making it easy to update and verify.

A firebase app will remain responsive regardless of network latency or internet connectivity. All writes to firebase will trigger local events immediately, before any data has been written to the server. Once connectivity is re-established, the client will receive any changes missed, synchronizing to the current server state.

Firebase abstracts the authentication functionality. The firebase has built in functionality for authenticating users with email, password, Facebook, twitter. Also can authenticate with the existing backend with the authentication tokens.


firebase can deploy the web apps in seconds with production grade static asset hosting. This provides features such as rolling back to the previous version within very less time. Every app gets the firebaseapp.com domain and paid app gets the custom domain. and paid apps can deploy to a custom domain.

references:
https://www.firebase.com/

Android Custom Compound Views

The intention is to create a compound view which actually displays a background image with 2 buttons 

This is accomplished by writing a class and subclassing it with Layout class and loading the layout xml with layout inflator.
like below. 


public class WeatherView extends LinearLayout {
    private View mValue;
    private ImageView mImage;
    
    public WeatherView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOrientation(LinearLayout.HORIZONTAL);
        setGravity(Gravity.CENTER_VERTICAL);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.weather_view_layout, this, true);
    }
    
    public WeatherView(Context context) {
        this(context, null);
    }
    
}

The complete files with layout XML, layout subclass and Activity layout xml can be downloaded from https://drive.google.com/file/d/0B0ZgwdHsnw1baTBuNngtdGk5Rnc/view?usp=sharing


references

Wednesday, March 30, 2016

Angular JS Two way data binding

In this step, application will control the order in which the items are listed. Dynamic ordering is implemented by creating new model property, wiring it with the repeater, and letting the data binging magic do the rest of the work. 

w.r.to UI, application now also displays a drop down box which lets the user control the order in which the items are listed. 

template looks like the below 

Search : input ng-model=“query”
Sort By: 
select ng-model=“orderProp”
option value=“name” Alphabetical /option
option value=“age” Newest /option
select 

ul class=“phones” 
li ng-repeat=“phone in phones| filter:query | orderBy:orderProp”
span {{phone.name}} /span
span {{phone.snippet}} /span

/li
/ul

Angular creates data binding between the select element and the orderProp model. orderProp is then used as input for orderBy filter. 

below is how the controller looks like 

var phonecatApp = angular.module(‘phonecatApp’,[]);

phonecatApp.controller = (‘phoneListControl’, function($scope)
{
$scope.phones = [
{‘name’ : ‘Nexus S’, ‘snippet’ : ‘Fast got furious’ , ‘age’ : 1},
{‘name’ : ‘MOto S’, ‘snippet’ : ‘Fast got furious Moto’ , ‘age’ : 2},
{‘name’ : ‘Droid S’, ‘snippet’ : ‘Fast got furious Droid’ , ‘age’ : 3},

];
$scope.orderProp = ‘age’;
}

Notice that when the app is loaded in the browser, "Newest" is selected in the drop down menu. This is because we set orderProp to 'age' in the controller. So the binding works in the direction from our model to the UI. Now if you select "Alphabetically" in the drop down menu, the model will be updated as well and the phones will be reordered. That is the data-binding doing its job in the opposite direction — from the UI to the model.

References:

Tuesday, March 29, 2016

iOS App with Swift crashes due to Certificate issue


Below was what the crash report indicated. 

[deny-mmap] mapped file has no team identifier and is not a platform binary: /private/var/mobile/Containers/Bundle/Application/B7B2BE25-BEE1-4DD0-B6BD-2BF4E4932862/TestApp.app/Frameworks/libswiftCore.dylib

 We found origins that caused this issue, related to a missing attribute in “Subject” field InHouse Certificates :
    It was
Subject: UID=269J2W3P2L, CN=iPhone Distribution: Company Name, O=Company Name, C=FR
    And now we can find a OU field in new certificates :
    

Subject: UID=269J2W3P2L, CN=iPhone Distribution: Company Name, OU=269J2W3P2L, O=Company Name, C=FR

The OU, which stands for organizational unit should be mandatorily present in the certificate it appears.

references:
https://www.airsignapp.com/ios-apps-using-swift-crash-when-signed-with-inhouse-certificate/

JavaPNS bug with 2KB payload

Starting iOS 8.0, Apple supports 2048 bytes of payload. Inorder to utilize it, application side we don’t need to make any changes, however, from the server side, if using JavaPNS library, we will have to update it to the latest versions 2.2 or 2.3 which claims to have raised that bar. However, in experience, it appeared that it is plagued by the Issue which gives exception like below 


Looking at the github source code, it appeared that the application still hardcodes the payload size to 256 and this can be found in the code PushNotificationPayload.java. 
Just changed that to 2048 and recompiled using the below, gave the latest code base and good to go to push lengthier messages! 

javac -cp .:bcprov-jdk15-146.jar:log4j-1.2.15.jar javapns/*.java javapns/communication/*.java javapns/communication/exceptions/*.java javapns/devices/*.java javapns/devices/implementations/basic/*.java  javapns/devices/exceptions/*.java javapns/feedback/*.java  javapns/notification/*.java javapns/notification/exceptions/*.java javapns/notification/management/*.java javapns/notification/transmission/*.java javapns/test/*.java

references

Angular JS - filtering repeaters

This section intended to showcase the full text search capability. In this example, the team made the controller untouched. 
the view is changed like this below 

div class=“container-fluid“
div class=“row”
div class=“col-md2”
Search : input ng-model=query
/div
div class=“col-md-0”
ul class=“phones”
li ng-repeat=“phone in phones | filter:query”
{{phone.name}}
p {{phone.snippet}}

The change here was that we added a standard input tag and also an angular filter function to process the input for the ng-repeat directive. 

Below are the items it tries to demonstrate by this

Data Binding: When the page loads, the Angular binds the name of the input field to a variable of same name in the data model and keeps both in sync

In this code, the data that user types into the input box is immediately available as filter input in the list repeater. When changes to the data model cause the repeater’s input to change, the repeater efficiently updates the DOM to reflect the current state of the model. 

Use of filter filter. The filter function uses the query value to create a new array that contains only those records that matches the query.  ngRepeat automatically updates the view in response to the changing number of phones returned by the filter filter. The process is completely transparent to the developer. 


references:

Monday, March 28, 2016

Static Vs Angular JS Template


In Angular, the view is a projection of the model through the HTML template. This means that whenever the model changes, Angular refreshes the appropriate binding points, which updates the view.

The view component is constructed by Angular JS from the template like below 

html ng-app=‘phonecatApp’ 
head
script src=‘bower_components/angular/angular.js
/head

body ng-controller=‘phonelistCtrl’
ul
li ng-repeat=“phones in phones”
span {{phone.name}}
p {{phone.snippet}}
/li
/ul
/body

/html

Now having the view is setup, we need the model and controller. The data model can be placed in the controller. The controller is just a constructor function that takes a $scope parameter. 

app/js/controller.js 

var phonecatApp = angular.module(‘phonecatApp’,[]);
phonecatApp.controller (‘phonelistCtrol’, function($scope)
{
$scope.phones = [
{'name': 'Nexus S',
            'snippet': 'Fast just got faster with Nexus S.'},
        {'name': 'Motorola XOOM™ with Wi-Fi',
            'snippet': 'The Next, Next Generation tablet.'},
        {'name': 'MOTOROLA XOOM™',
            'snippet': 'The Next, Next Generation tablet.'}
];
}

The ngController directive, located on the tag, references the name of our controller, PhoneListCtrl (located in the JavaScript file controllers.js).
The concept of scope in Angular JS is actually critical. A scope can be seen as glue between template, model and controller to work together.
Any change thats reflected in view happens in the model and vice versa. 

References:

Sunday, March 27, 2016

Supporting different layouts in Landscape and Portrait

This is comparatively simple if using Android studio. Below is what to be done.

Internally, this creates two different layout XML files.



This internally creates layout resource name like the one below 




references:
http://developer.android.com/guide/practices/screens_support.html

What is DSRC

Communications-based active safety applications use vehicle-to-vehicle (V2V) and vehicle-to-infrastructure (V2I) short-range wireless communications to detect potential hazards in a vehicle’s path – even those the driver does not see. The connected vehicle provides enhanced awareness at potentially reduced cost, and offers additional functionality over autonomous sensor systems available on some vehicles today. Communications-based sensor systems could potentially be a low-cost means of enabling hazard detection capability on all vehicle classes, but requires vehicles and infrastructure to be outfitted with interoperable communications capabilities.
    Dedicated Short Range Communications (DSRC) are the communications media of choice for communications-based active safety systems research because:
        
        It operates in a licensed frequency band.
        It is primarily allocated for vehicle safety applications by FCC Report & Order – Feb. 2004 (75 MHz of spectrum).
            It provides a secure wireless interface required by active safety applications.
            It supports high speed, low latency, short-range wireless communications.
            It works in high vehicle speed mobility conditions.
            Its performance is immune to extreme weather conditions (e.g. rain, fog, snow, etc.).
            It is designed to be tolerant to multi-path transmissions typical with roadway environments.
            It supports both vehicle-to-vehicle and vehicle-to-infrastructure communications.
            - See more at: http://www.its.dot.gov/DSRC/dsrc_faq.htm#sthash.Uh24Trrf.dpuf

references

Saturday, March 26, 2016

OpenWeatherMap to get the Weather info

this API is quite simple and easy to setup.

Just register on this website and get the API key. The usage is limited but enough to do some development tasks.

Once get the app Id, just insert into the API url like this below

http://api.openweathermap.org/data/2.5/weather?zip=560100,in&APPID={APP_ID}&units=metric

The result was something like this below

{"coord":{"lon":77.6,"lat":12.98},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":25,"pressure":1018,"humidity":47,"temp_min":25,"temp_max":25},"visibility":6000,"wind":{"speed":4.53,"deg":131.003},"clouds":{"all":0},"dt":1459020600,"sys":{"type":1,"id":7823,"message":0.0122,"country":"IN","sunrise":1458953348,"sunset":1458997252},"id":1277333,"name":"Bangalore","cod":200}

references
http://code.tutsplus.com/tutorials/create-a-weather-app-on-android--cms-21587

Acer 200 WiFi Disconnect

The WiFi router was giving a wifi disconnect problem whenever Youtube was playing on my Acer 200 Iconia 10" tablet. This was kind of strange and first thought something to do with the YouTubePlayerView that was used in the app. But then found that the problem do exist even if use the native YouTube Player. There was no software upgrade available to think that it might have been fixed by the upgrade that was pending. Roaming around the forums, found that this could go away if the router can give the static IP to this tablet. With this, added a mapping in the WiFi router for this and IP and the MAC address and it appeared to work find later.

 

references:
http://www.androidtablets.net/threads/wifi-turning-off.20647/

Android Mute and un-mute system volume

At basic level, below two code snippets can do this.

public static void unmuteSystemAudio()
    {
        try
        {
            AudioManager audio = (AudioManager) getAppContext().getSystemService(Context.AUDIO_SERVICE); audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
        }
        catch (Exception ex)
        {
            Utils.log("Exception while unmutting system audio");
            ex.printStackTrace();
        }
    }
    
    public static void muteSystemAudio()
    {
        try
        {
            AudioManager audio = (AudioManager) getAppContext().getSystemService(Context.AUDIO_SERVICE); audio.setRingerMode(AudioManager.RINGER_MODE_SILENT);
        }
        catch (Exception ex)
        {
            Utils.log("Exception while muting system audio");
            ex.printStackTrace();
        }

    }

references
http://developer.android.com/reference/android/media/AudioManager.html

Wednesday, March 23, 2016

Quirks of Android MediaPlayer API

MediaPlayer when running in services and data source as streaming URLs especially will have to take care of the below 

the MediaPlayer type needs to be AudioStreamType like below 

mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();

While normally the prepare can be fast, to be a robust application, it needs to listen for the prepare callbacks. the call to prepare() can take a long time to execute, because it might involve fetching and decoding media data. So, as is the case with any method that may take long to execute, you should never call it from your application's UI thread. Doing that will cause the UI to hang until the method returns, which is a very bad user experience and can cause an ANR (Application Not Responding) error. Even if you expect your resource to load quickly, remember that anything that takes more than a tenth of a second to respond in the UI will cause a noticeable pause and will give the user the impression that your application is slow.

Instead of creating a separate thread, we could also do this by using the method prepareAsync. This method starts preparing the media in the background and returns immediately. When the media is done preparing, the onPrepared() method of the MediaPlayer.OnPreparedListener, configured through setOnPreparedListener() is called.

One another important item is to be careful is to release the resources which was used by the player. This can be achieved by calling release() method. 

Because the Android system tries to conserve battery while the device is sleeping, the system tries to shut off any of the phone's features that are not necessary, including the CPU and the WiFi hardware. However, if your service is playing or streaming music, you want to prevent the system from interfering with your playback.

To ensure that the CPU continues running while your MediaPlayer is playing, call the setWakeMode() method when initializing your MediaPlayer. Once you do, the MediaPlayer holds the specified lock while playing and releases the lock when paused or stopped:

mMediaPlayer = new MediaPlayer();
// ... other initialization here ...
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);

the wake lock acquired in this example guarantees only that the CPU remains awake. If you are streaming media over the network and you are using Wi-Fi, you probably want to hold a WifiLock as well, which you must acquire and release manually. 

WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");

wifiLock.acquire();

When network is no longer needed, can use the release method to release the lock

wifiLock.release();


references:

Tuesday, March 22, 2016

Is Google deprecating some of the Places services?


 Google has recently announced and already stopped supporting the places API search filter accepting multiple values.
The intention behind this was to make the search result match between google maps API and places API. Places API now uses 
Google Map search services to give the result. With this change, the type filter which was used to specify the place type such as 
restaurants etc cannot accept multiple values. 

Beginning Feb 16, 2016, we are replacing the types restriction parameter with a new type search parameter. If you have been using the types parameter for Nearby Search, Text Search or Radar Search you will be affected.

Requests using the types parameter and those specifying multiple types (for example, types=hospital|pharmacy|doctor) will continue to return results until Feb 16, 2017, but we do not recommend using multiple types in a search request. After that date, requests with multiple types will no longer be supported. To ensure the best possible search results for your users, we recommend using a single type in search requests.

example is below 

https://maps.googleapis.com/maps/api/place/textsearch/json
    ?type=airport
    &location=-33.87,151.21
    &radius=5000
    &key=

In addition, we are amending the list of supported types. The types establishment, food, health, general_contractor, finance and place_of_worship, will not be available as searchable types from Feb 16, 2017. However these types will still be returned in search and details results.

    
references:

http://googlegeodevelopers.blogspot.in/2016/02/changes-and-quality-improvements-in_16.html

How to assign Static IP for a MAC address in Router


here we can see how to configure a static IP address to a MAC address. Below is a setup for Beetel WiFi router 



In this case, added the IP 192.168.1.6 and associated it with the MAC address 00:22:5F:63:9A:BF. 
Once a new entry is added, it needs to be saved, In the beetel case, the SAVE button is at the bottom of the page
One might think the add option is missing easily. 

Now once the mapping is added, the router can be restarted and find that the association is not changed. 
this should not change unless the mapping is removed.  



references:

Angular JS - What is Bootstrap

recommended path for integrating the Angular JS is to place the script tag at the bottom of the page. Placing script tags at the end of the page improves app load time because the HTML loading is not blocked by loading of the angular.js script. We can get the latest bits from http://code.angularjs.org.

Place ng-app to the root of your application, typically on the tag if you want angular to auto-bootstrap your application

There are two types of initialization

1. Automatic initialization 
Angular JS automatically initialzes DOMContentLoaded event or when the angular script is evaluated and if at that time if document.readyState is set to complete. At this point angular js looks for ng-app directive and does the below 

a. load the module associated with the directive 
b. create the application injector
c. compile the DOM treating the ng-app directive as the root of compilation. this allows to tell it to treat only a portion of DOM as the angular application 

I can add :{{1+2}}.

Sunday, March 20, 2016

Installing Apache Tomcat on Mageia

Its as easy as below few steps

Download the tar.gz distribution from the Apache website


tar xvzf apache-tomcat-7* -C /tmp/

Relocate Apache tomcat 7 

su -c "chmod -R root:root /tmp/apache-tomcat*
mv /tmp/apache-tomcat-7* /opt"

Start and Stop tomcat Server by the following two commands

/opt/apache-tomcat-7*/bin/startup.sh
/opt/apache-tomcat-7*/bin/shutdown.sh

references:
http://tutorialforlinux.com/2014/06/16/how-to-install-and-getting-started-apache-tomcat-7-for-mageia-4-cauldron-32-64bit-linux-easy-visual-guide/

Android What is Remote Messenger Service


If you need to be able to write a Service that can perform complicated communication with clients in remote processes (beyond simply the use of Context.startService to send commands to it), then you can use the Messenger class instead of writing full AIDL files.

An example of a Service that uses Messenger as its client interface is shown here. First is the Service itself, publishing a Messenger to an internal Handler when bound:


On the activity side, we should keep a Messenger instance to communicate to the service. When creating a messenger, we can give an instance of Handler and that subclass can override the handleMessage function to handle the messages from the service. 

The other main component is ServiceConnection instance, which is the main interface to communicate with the service. The main two methods in this are, onServiceConnected and onServiceDisconnected. 

when onServiceConnected gets called back, it receives and IBinder object, this is tied with the second Messenger reference. In short, there are two Messenger Instances, one is representing the service connection from Service and the second one is Messenger for Service connection to send the messages to. 

References:

Thursday, March 3, 2016

Categories vs Class Extensions vs Class Clusters

We can use categories to define additional methods of an existing class—even one whose source code is unavailable to you—without subclassing.

One can also use categories of your own classes to:

Distribute the implementation of your own classes into separate source files—for example, you could group the methods of a large class into several categories and put each category in a different file.

Declare private methods.
You add methods to a class by declaring them in an interface file under a category name and defining them in an implementation file under the same name. The category name indicates that the methods are an extension to a class declared elsewhere, not a new class.

#import "SystemClass.h"

@interface SystemClass (CategoryName)
// method declarations
@end

#import "MyClass.h"

@interface MyClass (PrivateMethods)
// method declarations
@end

@implementation MyClass
// method definitions
@end


A class cluster is an architecture that groups a number of private, concrete subclasses under a public, abstract superclass. The grouping of classes in this way provides a simplified interface to the user, who sees only the publicly visible architecture. Behind the scenes, though, the abstract class is calling up the private subclass most suited for performing a particular task. For example, several of the common Cocoa classes are implemented as class clusters, including NSArray, NSString, and NSDictionary.

You create and interact with instances of the cluster just as you would any other class. Behind the scenes, though, when you create an instance of the public class, the class returns an object of the appropriate subclass based on the creation method that you invoke. (You don’t, and can’t, choose the actual class of the instance.)

NSString *string1 = @"UTF32.txt";
NSString *string2 = [NSHomeDirectory() stringByAppendingPathComponent:string1];
NSTextStorage *storage = [[NSTextStorage alloc] initWithString:string2];
NSString *string3 = [storage string];

Benefits
The benefit of a class cluster is primarily efficiency. The internal representation of the data that an instance manages can be tailored to the way it’s created or being used. Moreover, the code you write will continue to work even if the underlying implementation changes.


references:

NSURLCache notes

NSURLCache provides a composite in-memory and on-disk caching mechanism for URL requests to your application. As part of Foundation’s URL Loading System, any request loaded through NSURLConnection will be handled by NSURLCache.

Below are few cache policies 

NSURLRequestUseProtocolCachePolicy: Caching logic defined in the protocol implementation is used for a particular URL load request. This is the default policy.
NSURLRequestReloadIgnoringLocalCacheData: Data should be loaded from the originating source. No existing cache data should be used.
NSURLRequestReloadIgnoringLocalAndRemoteCacheData: Not only should the local cache data be ignored, but proxies and other intermediates should be instructed to disregard their caches so far as the protocol allows.
NSURLRequestReturnCacheDataElseLoad: Existing cached data should be used, regardless of its age or expiration date. If there is no existing data in the cache corresponding to the request, the data is loaded from the originating source.
NSURLRequestReturnCacheDataDontLoad: Existing cache data should be used, regardless of its age or expiration date. If there is no existing data in the cache corresponding to the request, no attempt is made to load the data from the originating source, and the load is considered to have failed, (i.e. “offline” mode).
NSURLRequestReloadRevalidatingCacheData: Existing cache data may be used provided the origin source confirms its validity, otherwise the URL is loaded from the origin source.


Request Cache Headers

By default, NSURLRequest will use the current time to determine whether a cached response should be returned. For more precise cache control, the following headers can be specified:

If-Modified-Since - This request header corresponds to the Last-Modified response header. Set the value of this to the Last-Modified value received from the last request to the same endpoint.
If-None-Match - This request header corresponds to the Etag response header. Use the Etag value received previously for the last request to that endpoint.

Server response can include any of the below 

Cache-Control - This header must be present in the response from the server to enable HTTP caching by a client. The value of this header may include information like its max-age (how long to cache a response), and whether the response may be cached with public or private access, or no-cache (not at all). See the Cache-Control section of RFC 2616 for full details.

Last-Modified - The value of this header corresponds to the date and time when the requested resource was last changed. For example, if a client requests a timeline of recent photos, /photos/timeline, the Last-Modified value could be set to when the most recent photo was taken.
Etag - An abbreviation for “entity tag”, this is an identifier that represents the contents requested resource. In practice, an Etag header value could be something like the MD5 digest of the resource properties. This is particularly useful for dynamically generated resources that may not have an obvious Last-Modified value.


references:

Optimize Network performance with Gzip compression

Below is how it normally works 

1. The browser sends a header telling the server it accepts compressed content (gzip and deflate are two compression schemes): Accept-Encoding: gzip, deflate
2. The server sends a response if the content is actually compressed: Content-Encoding: gzip

If the server doesn’t send the content-encoding response header, it means the file is not compressed (the default on many servers). The “Accept-encoding” header is just a request by the browser, not a demand. If the server doesn’t want to send back compressed content, the browser has to make do with the heavy regular version.

Now there is also work to set this up in the server 

On IIS, link here gives steps to enable compression. https://technet.microsoft.com/en-us/library/cc771003(WS.10).aspx It allows compression of contents which are static, dynamic or both
On Apache server, http://httpd.apache.org/docs/2.0/mod/mod_deflate.html this link gives instruction to enable compression. 

mod_deflate is easier to set up and is standard.
mod_gzip seems more powerful: you can pre-compress content.

Below are some ways to test if the compression is enabled 

Online: Use the online gzip test to check whether your page is compressed. (http://www.gidnetwork.com/tools/gzip-test.php)
In your browser: Use Web Developer Toolbar > Information > View Document Size (like I did for Yahoo, above) to see whether the page is compressed.
View the headers: Use Live HTTP Headers to examine the response. Look for a line that says “Content-encoding: gzip”.

references


Swift Building Basic UI

The Apple reference gives a Food tracker app building UI. 

the basic UI had one label, one text filed and a button. The tutorial began by dragging and dropping the components to the view controller and then it talks about adopting the auto layout. 

Few items to note are: 

1. Adding spacing between components in stack view. This can be done by Selecting Stack view in the outline view and on the attribute inspector, in the spacing field, enter the value desired. 
2. Now we can align the Stack view w.r.to the parent container and for this need to use the Pin menu. We can select the vertical or horizontal constraints here. 
3. Having the #2 done, the Text field in the stack view was not stretching. This is because the default size is intrinsic size. This can also be Pinned after selecting the horizontal constraints according to the spacing desired. Also, can change the Intrinsic size to place holder Intrinsic content size refers to the minimum size needed to display all the content in the view. You can assign UI elements a placeholder intrinsic content size if you need to design a UI for a different size than you can anticipate at design time. Right now, the text field’s only content is its placeholder string, but the actual text a user enters could be longer than that.

Having the 3 steps above done, the UI will be something like this. 
Next part was connecting the built UI to the code. 

In Swift, instead of using #pragma, we need to use //MARK:
The IBoutlet can be created by just dragging the component to the code area in assistant editor. when we do this for the textfield, we can notice that the IBoutlet get created with an implicitly unwrapped optional. (optional that is always having value after it first set) 


For adding actions, again drag and drop to the function area. An area can be made as method area by declaring //MARK: Actions. Now once drag and drop the button, the popup appears where we can fill in the attributes such as UIButton, etc. 
In Swift, AnyObject is a type used to describe an object that can belong to any class. Specifying the type of this action method to be UIButton means that only button objects can connect to this action. Although this isn’t significant for the action you’re creating right now, it’s important to remember for later.

Implementing the protocols is easy, in Objective C, we had to use and in the Swift, we can do this by just writing with a comma separated list. 

References:

Wednesday, March 2, 2016

iOS UIStackView

With the introduction of UIStackView, the alignment and auto layout tasks become trivial. Stack views provide a way to lay out a series of views horizontally or vertically. By configuring a few simple properties such as alignment, distribution, and spacing, you can define how the contained views adjust themselves to the available space. A stack view can distribute its views along its axis in various ways, and one of the ways is with an equal amount of spacing between each view. Embedding existing views into a new stack view is easy. First, select all of the buttons at the bottom of the Spot Info View Controller scene by clicking on one, then Command-click on the other two:

Once selected, click on the new Stack button in the Auto Layout toolbar at the bottom right of the storyboard canvas. Another option is to use Editor > Embed In > Stack View

When we embed a view in a stack view, any constraints to other views are removed. Now, click the Pin button on the Auto Layout toolbar to add constraints to it: Adding constraints is same as any other view. Double-check the numbers for the top, leading, trailing, and bottom constraints and make sure that the I-beams are selected. Then click on Add 4 Constraints. However, when doing this the components inside get stretched.

The property that determines how a stack view lays out its views along its axis is its distribution property. Currently, it’s set to Fill, which means the contained views will completely fill the stack view along its axis. To accomplish this, the stack view will only expand one of its views to fill that extra space; specifically, it expands the view with the lowest horizontal content hugging priority, or if all of the priorities are equal, it expands the first view.

If we want to distribute the spacing equally, go to the Attributes inspector. Change the Distribution from Fill to Equal Spacing:

In order to solve this problem without a stack view, you would have had to use spacer views, one between each pair of buttons. You’d have to add equal width constraints to all of the spacer views as well as lots of additional constraints to position the spacer views correctly.

References:

http://www.raywenderlich.com/114552/uistackview-tutorial-introducing-stack-views