Saturday, October 31, 2015

Linphone - How it manages IPv6 connection in iOS


Android Bluetooth - Hands on


Android Bluetooth APIs - Learning Part II

Below is the snippet to retrieve list of bonded devices. 

Set pairedDevices = btAdapter.getBondedDevices();

getName() returns the public identifier of the devices
getAddress() returns the MAC address of the device 

In order to find the nearby devices, which is called scanning we need to use the below code

btAdapter.startDiscovery() is the method to start scanning operation. btAdapter.cancelDiscovery() will cancel the initiated scanning 

These two methods are working via Asynchronous feedbacks by Broadcast Receivers. 

private final BroadcastReceiver receiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action))
{
BluetoothDevice device = intent.getParcellableExtra(BluetoothDevice.EXTRA_DEVICE);
}
}
}

Connecting to a Device:

Similar to any other connection, there is a Server and Client which communicates via RFCOMM sockets. 
On Android, RFCOMM sockets are represented as BluetoothSocket object. 

Below is the code to connect to a Bluetooth Device 

public class ConnectThreads extends Thread
{
private BluetoothSocket bTSocket;
public boolean connect(BluetoothDevice btDevice, UUID uuid)
{
BluetoothSocket socket = null;
try
{
socket = btDevice.createRFCommSocketToServiceRecord()
}
catch(Exception ex)
{
ex.printStackTrace();
}
try
{
socket.connect();
}
catch(Exception ex)
{
ex.printStackTrace();
try
{
}
catch(Excpetion ex)
{
}
}

}
}


References:

Linphone Management of Bandwidth parameter

References:
https://www.linphone.org/docs/liblinphone/group__media__parameters.html#ga1e0c01a25f78d14c6813213adf795e54

SIP SDP bandwidth information

The SDP includes an optional bandwidth attribute with the following syntax 

b=:

where is single alpha numeric word giving the meaning of the bandwidth figure, and where the default units of 
bandwidth value is kilobits per second. This attribute specifies the proposed bandwidth to be used by the session or media. 

The typical use is with the modifier “AS” (Application specific Maximum) which may be used to specify the total bandwidth for a 
single media stream from one site (source)

another modifier value is CT. If the bandwidth of a session or a media in a session is different from the bandwidth implicit from the scope, 
a b=“CT” line should be supplied for the session giving the proposed upper limit to the bandwidth used (the “conference total” bandwidth) 
The primary purpose of this is to give an approximate idea as to whether two or more sessions can co-exist simultaneously. when using CT 
modifier with RTP, if several RTP sessions are part of the conference, the conference total refers to the total bandwidth of all the RTP sessions. 


References:

Free Icon download Websites

Quirks of Unzipping on MAC

Some of the files were not able to be unzipped using either “unzip” command or “ditto” command via terminal
however, since they were getting opened perfectly using the “Archive Utility”, one option was to use the 
terminal to open such files. e.g. below 

open -a "Archive Utility" 0B9822F3-FE6C-4FB6-AB47-C98DA932279D_205155390.zip

The only inconvenience is that we cannot specify the destination folder. 

This can be automated using a simple shell script like this 

for file in *; do
echo $file
open -a "Archive Utility" $file
done


References:

What is needed for Support IPv6

An operating system that support IPv6: Windows Vista and modern versions and Mac OS and Linux latest versions support IPv6. Windows XP doesnt, and we should not be using XP anymore. 

A router with IPV6 support: Most of the modern routers comes with IPv6 support 

An ISP that supports IPV6. 


The below page helps to test the IPv6 http://ds.testmyipv6.com/ 

The IPv6 only test:

If we attempt to connect to this server and times out, then it means that we don’t have IPv6 path to the server. The below could be possible reason for this

1. The client is not having globally routable address on the internet and therefor not actually making the connection to this server 
2. The client is IPv6 capable, but does not know that it is limited to the local network. But there is no IPv6 connectivity beyond the router 

If the browser returns an error saying that the host cannot be found, then the DNS servers that we are using don’t know how to look up the address of the server based on the hostname. They are unable to resolve the AAAA record. If one is using the DNS server addresses provided by the ISP, then we need to ring them up and ask to fix ASAP. 

If we are using local gateway or router for DNS, then router is not capable or forwarders used by the router (likely the ISP’s servers) is not capable. 

IF browser is able to connect to IPV6 only page, but still shows red box when taking the Dual Stack test, the browser seems to be preferring IPV4 over IPV6, which is undesirable. 



References

Serializing the objects Java

Serialization is quite simple, if we have requirement to Serialize and ArrayList that contains a number of Objects, below are the steps to do

1. Create the object that goes into the array list as Serializable objects
2. Optionally, add a field into the object which can tell the version of the class structure.

Now just add to the array list and serialize the array list, be

public class Accessory implements Serializable

{
    private int type;
    private int state;
    private String name;
    private String uuid;

    public Accessory(int type, int state, String name, String uuid)
    {
        this.type = type;
        this.state = state;
        this.name = name;
        this.uuid = uuid;
    }
}

 public void saveAccessories(ArrayList accessoryList)
    {
        try
        {
            FileOutputStream fos= new FileOutputStream("myfile");
            ObjectOutputStream oos= new ObjectOutputStream(fos);
            oos.writeObject(accessoryList);
            oos.close();
            fos.close();
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
    
    public ArrayList loadAccessories()
    {
        try
        {
            FileInputStream fis = new FileInputStream("myfile");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Object obj = ois.readObject();
            ois.close();
            return (ArrayList)obj;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return null;
    }

References:
http://www.journaldev.com/2452/java-serialization-example-tutorial-serializable-serialversionuid

Friday, October 30, 2015

iOS Push Notification - Debugging

Since the app is not receiving the valid push notification token from OS, there are a few reasons why the APNS token does not get delivered to the app. One of them is network is blocking the 5223 for inbound and outbound TCP/TLS traffic. 

If still not receiving the notification, we can figure out few things by installing a debug profile at the link below, which will let us give the device level Apple Notification server connection logs


Once installed, please restart the device while connected to Xcode, Once the device powers up and app is launched, we can see the logs in the Xcode console.

In the log, there will be logs from the process “apsd” which will help us analyze what is happening. 


If would prefer to delete the is profile at later point, can do this by navigating to Settings > General > Profiles  Delete APS logging profile. 

References:

Android - Creating a Dynamic Grid view

For a sample application, i was trying to include a Dynamic grid view. The git hub project that is in the reference section looked to be 
really useful. noting down few points on this. 

Below are the main things that attracted to look into it. 

- On long tap, the grid enters to edit mode
- when in edit mode, the icons jerk to give an iPhone like animation 
- On tap of the icon, it just does the action as expected. 
- When dragging an icon in edit mode, it adjusts each other nicely
- when dragged by holding, the view scrolls as well. 

Below are the main classes in the project. 

- DynamicGridView => Main View for the Grid view 
- DynamicGridUtils => Utils methods for doing the model level tasks such as reordering, swapping etc. 
- DynamicGridAdapterInterface => interface to be used with grid view 
- AbstractDynamicGridAdapter -> 
- BaseDynamicGridAdapter -> 


Below are the steps to integrate this into a new project. 

1. On the new project right click the project and select new Module 
2. On the new module window, select import existing project 
3. Specify the source directory and add the dynamic grid project from the git hub download 
4. Open module settings, and add the dynamic grid as dependancy to the new app. 


References:

Tuesday, October 20, 2015

Android TimerTask on Background Service

For creating a timer task and running it periodically, say for e.g. making a network ping periodically can be achieved by the below code

class TimeDisplayTimerTask extends TimerTask {
    
    @Override
    public void run() {
        // run on another thread
        mHandler.post(new Runnable() {
            
            @Override
            public void run() {
                
                AppUtils.infoLog("--- Triggering Location Check ---");
                displayTimeInfo();
            }
            
        });
    }
}


if(mTimer != null) {
    mTimer.cancel();
}   // recreate new
mTimer = new Timer();
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);

Handler is mainly used to post data from background thread to UI thread. 

References:

Saturday, October 17, 2015

Android Dialog With Radio Buttons

The code is simple 

final CharSequence[] photo = {"Manage Devices","Manage Connections"};
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);

alert.setTitle("Settings For");

alert.setSingleChoiceItems(photo, -1, new
                           DialogInterface.OnClickListener() {
                               @Override
                               public void onClick(DialogInterface dialog, int which) {
                                   Log.v(LOG_TAG,"chosen "+which);
                               }
                           });
alert.show();


References:

Android Custom Adapter for Grid View

The aim was to display a grid icon and the label corresponding to it, just like below screenshot

This can be done by giving a layout for each cell and this layout view is returned as a layout defined in this file

A sample layout for this is

"1.0" encoding="utf-8"?
android:id="@+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="5dp"

android:layout_height="64dp"
android:id="@+id/imageView1"
android:layout_width="64dp"
android:src="@drawable/ic_launcher"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"

android:text="TextView"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_below="@+id/imageView1"
android:layout_marginTop="2dp"
android:layout_centerHorizontal="true"
android:textSize="18sp"
android:ellipsize="marquee"



In the getView Method of the Adapter class, below will be the code 

public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ViewHolder view;
    LayoutInflater inflator = activity.getLayoutInflater();
    
    if(convertView==null)
    {
        view = new ViewHolder();
        convertView = inflator.inflate(R.layout.gridview_row, null);
        
        view.txtViewTitle = (TextView) convertView.findViewById(R.id.textView1);
        view.imgViewFlag = (ImageView) convertView.findViewById(R.id.imageView1);
        
        convertView.setTag(view);
    }
    else
    {
        view = (ViewHolder) convertView.getTag();
    }
    
    view.txtViewTitle.setText(listCountry.get(position));
    if(itemStates[position] == 0) {
        view.imgViewFlag.setImageResource(listFlagOff.get(position));
    }
    else
    {
        view.imgViewFlag.setImageResource(listFlag.get(position));
    }
    return convertView;
}
}

It is convenient to have tag as object for each view. This way we can associate arbitrary object. Where as in iOS, the tag has to be always int. 


References:

Thursday, October 15, 2015

Hands On With GitHub Repository - Part II

The main purpose of forking a repository is to propose changes and in other words, work together. Below are the steps to do that 

1. Setup the Git 
2. Clone the repository to the local repository 

To clone, we can get the clone url and enter the following in the terminal 

git clone

after cloning, we can see the details of the remote repository like this 

git remote -v 

 git remote -v
origin https://github.com/mrrathish/TestGitProj.git (fetch)
origin https://github.com/mrrathish/TestGitProj.git (push)


in the above, essentially, it like the format below 

origin https:github.com//

Now we need to add upstream repositories so that we can sync up. 

 git remote add upstream https://github.com/mrrathish/TestGitProj.git

After adding the upstream info, the remote -v command will give the details like below 

git remote -v
origin https://github.com/mrrathish/TestGitProj.git (fetch)
origin https://github.com/mrrathish/TestGitProj.git (push)
upstream https://github.com/mrrathish/TestGitProj.git (fetch)
upstream https://github.com/mrrathish/TestGitProj.git (push)

In the above, the original format of upstream is, 

upstream https://github.com//

Now everything is setup for Synching. Below gives info on how to sync the fork 

to sync the online repository with the local one, below are the steps

1. git fetch upstream (this fetches the commits from master into the local branch upstream/master) 
2. git checkout master (checkout fork’s local branch) 
3. git merge upstream/master (merges the changes from upstream/master into the local master. This brings fork’s master in sync with the upstream master)


Note that Synching the fork only updates the local copy of the repository. To update the fork on github, one must Push the changes 

References:

Tuesday, October 13, 2015

Hands on With GitHub repository - Part I

1. Set up A repo

first of all few configurations we need to do for the git repository. 

1. name  => git config —global user.name = “testgitun”
2. email address => git config —global user.email = “testgitun.gmail.com”

Authentication with GitHub from Git 

When connecting to GitHub repository from Git, we need to authenticate with Github using either HTTPS or SSH
If connecting via HTTPS the password can be cached using a Credential Helper. 
If clone with SSH, we must generate SSH keys on each computer we use to pull or push from GitHub. 

2. Create A Repo 

To put project in GitHub, first we need to create a repository for it to live in. 
The Create New repository option is very easily locatable and To create a new repository, just need to provide the name and description of the project. 
Free accounts can only create public repos while the paid accounts can create private repositories. 

When creating a git repo, we have an option to add a README file. The examples in github is explaining few concepts around this. The github page itself gives option to 
edit the content and preview. Once after preview, we can commit. the commit can be into the same master branch or we can create a new branch for this commit and generate a pull request. 

When the pull request is generated, it appears on the github page and one can merge the changes and delete the branch that came in the pull request. 


3. Forking A Repo 

Fork is a copy of a repository. Forking allows us to do free experiments without affecting the original project. 

Below is the usual practice: 

- Fork Some one else’s project 
- Make bug fix
- Submit a pull request 


References:

Monday, October 12, 2015

Android Bluetooth Scanner - Starter Basics

Below are the tasks intended in this sample 

- Enable bluetooth on a device 
- Display a list of paired devices 
- Discover and list nearest Bluetooth devices 
- Connect and send data to another bluetooth device 

There are two kinds of permissions 

1. BLUETOOTH => used to connect, disconnect and transfer data with another bluetooth device 
2. BLUTOOTH_ADMIN => allows to discover new bluetooth device and change device’s bluetooth settings



Application will need to use Bluetooth adapter for interfacing with the Bluetooth. 

BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();

if the Adapter is returned to be null, then the device does not have the Bluetooth feature

Application can get to know if the Bluetooth is enabled or not by using the API isEnabled. If not 
enabled, it can enable it by using an intent provided by Android

if(!btAdapter.isEnabled())
{
Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBT,REQUEST_BLUETOOTH);
}

A bluetooth device can be in any of the below states from perspective of Mobile Device 

- Unknown 
- paired 
- connected 

Paired devices know each other’s existence and share a link key, which can be used to authenticate, resulting in a 
connection. Devices are automatically paired once encrypted connection is established. 

Connected devices share RFCOMM channel, allowing them to send and receive data. A device may have many paired devices
but it can have only one connected devices at a time. 

References:

iOS Work arounds with the ATS in Xcode 7 & iOS 9.0

In iOS 9.0, ATS enforces best practices during network calls, including the use of HTTPS. 

If we want to avoid the ATS enforcement, by manually adding a plist entry, it is possible 


This above is mainly useful if App is trying to connect to some arbitrary sites for e.g. WebBrowser

If app is trying to connect to certain known domains that doesnt for time being support TSL 1.2, 
below can be used. 

NSExceptionDomains
<!— include to allow subdomains
<!— include to allow HTTP requests
<!— Include to specify minimum TLS version 

References:

Sunday, October 11, 2015

Swift Learning - Protocols Learning

The concept of Protocols is same as that of Objective C. It provides a blue print for methods, properties. 

e.g is like below 

protocol TestProtocol 
{
var simpleDesc: String {get}
func adjust() 
}

the {get} followed by simpleDesc indicates that it is read only. 

Protocols are like first class types, which means that they can be treated like other named types. 

class SimpleProtocol2: ExampleProtocol 
{
var SimpleDescription: String = “Another very simple class”
fun adjust()
{
simpleDescroption += “adjusted”
}
}

var protocolArray : [ExampleProtoocl] = [SimpleClass(), SimpleClasse(), Simpleclass()]


References:



Android Fragments - Basic learning

Fragment is ui component that can live in an activity. A fragment is not a view by itself. instead, it has view inside. Because it is not a view, the process of adding fragment to activity is different. A fragment is added to ViewGroup inside an activity. The Fragments view is displayed this ViewGroup. 

Below are the steps to create Fragments 

- Create a Fragment Class 
- Create a Fragment Layout XML 

The subclassed Fragment class needs to override the onCreateView method inherited from the Fragment class. 

The onCreateView gets the LayoutInflator, ViewGroup and Bundle as parameters 

import android.app.Fragment;

public class TestFragment extends Fragment 
{
@override 
public View onCreateView(LayoutInflator inflator, ViewGroup group, Bundle savedInstanceS)
{
View rootView = inflator.inflate(R.layout.test_fragment,group,false);
return rootView;
}
}


Below is the code to add Fragment to the activity 

public class TestActivity extends Activity
{
@override 
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
if(savedInstance == null)
{
getFragmentManager()
.beginTransaction()
.add(R.id.fragmentParentViewGroup,new TestFragment())
.commit();
}
}
}

The fragment is created inside the if statement. Unlike other View components, Activity remembers that what fragments were added to the Activity. Therefore we should add the fragment only once to the Activity. 

References:

Friday, October 9, 2015

Enumeration and Structures in Swift

Enumerations and structures also has similar capabilities as of Classes in Swift. 

enum Rank: Int 
{
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDescription() -> String 
{
switch self
{
case .Ace:
return “Ace”
case .Jack:
return “Jack”
case .Queen
return “Queen”
case .King
return “King”
default:
return String(self.rawValue)
}
}
}

let ace = Rank.Ace
let rawAceRawValue = ace.rawValue


we can use the init?(rawValue:) initializer to make an instance of an enumeration from a raw value. 

if(let convertedRank = Rank(rawValue:3))
{
let desc = convertedRank.simpleDescription()
}

The raw values are not really required because the members of an enumeration are actual values. 

struct is used to define a structure. 

struct Card 
{
  var rank:Rank
var suite : Suit
func simpleDescription() -> String 
{
return “suite has \(rank.simpleDescription())”
}
}

let structinit = Card (rank:.Three, suite:.Spades) 

References:


Thursday, October 8, 2015

Swift Learning - classes and initializers

class Shape
{
var numberOfSide = 0

init(name:String)
{
self.name = name
}

func simpleDescription() -> String 
{
return “A shape with number of sides \(numberOfSide)”
}
}

to create an instance of the class, just put a parentheses 

var shapeObj = Shape()
shapeObj.numberOfSides = 10
var shapeDescription = shapeObj.simpleDescription()

init is called to specify the initializer. 

var shapeObj = Shape(name:”SmpleShape”)

Like other programming languages, here also we have inheritence concept A class can only inherit from one class. 
Application can use the the override keyword to override a method. If did not use, the compiler will give error. 

There is a concept called fail able initilizer, which is represented by init? fail-able initializer can return nil after initialization. 

e.g. 

class Circle:NamedShape
{
var radius : Double

init?(radius:Double, name:String)
{
self.radius = radius
super.init(name:name)
if (radius < 0 )
{
return nil
}
}
}

A designated initializer indicates that its one of the primary initializers of a class. any initializer within a class must ultimately call through to a designated initializer. A convenience initializer is a secondary initializer which adds additional behavior for customization, but ultimately should go through the designated initializer. designated and convenience keywords are used for indicating this respectively. 

A required keyword next to an initializer indicates that every subclass of the class that has initializer must implement its own version of the initializer. 

type casting is a way to check the type of instance and to treat that instance as if it is a different superclass or subclass somewhere else in its own hierarchy. 

A constant or a variable of a certain type may actually refer to an instance of subclass behind the scenes. If this is the case, using the typecast operator, we can downcast to that type. 

Because down casting can fail, the type cast operator comes in two forms. as? gives an optional value of the type to which it is attempted to down cast to. as! downcasts and also force unrwaps the result as a single compound action. 

as? to be used when we are not sure the downcast will succeed. as! to be used if we are sure the downcast will succeed. 

e.g. is like below 

if let triangle = shape as Triangle 
{
triangle++
}

References:

Wednesday, October 7, 2015

Swift Functions - Basics I

fun is used to declare a function. A function declaration can have zero or more parameters, written as name:Type. the function return type is written after the name of the function after parameter list with -> 

func greet(name:String, day:String) -> String 
{
return “Hello \(name), today is \(day).”
}

We can call a function by following its name with a list of arguments in parentheses. The first argument need not have its name, the subsequent ones should have. 

for e.g. 


greet(“anna” day:”tuesday”)

Swift can have Function that return multiple values 

func minmax(array:[Int]) -> (min:Int, max:Int)
{
return (5,10)
}

let bounds = minmax([5,6,7,8,9,10])

print ("min is \(bounds.min) and max is \(bounds.max)")

The return types can be optional also and optional return values is represented with ? 

for e.e.g 

func minmax(array:[Int]) -> (min:Int, max:Int) ?
{
return (currentMin, currentMax)
}

if (let bounds = minmax([1,2,3,4]))
{
       print("min is :\(bounds.min) and max is: (bounds.max)")
}

There are lot more in functions! 


references:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

Monday, October 5, 2015

Essentials of Swift - Learning Part II

Control Flow: 

There are two types of control flow statements 

1. Conditional Statements => e.g If and switch 
2. Loops => e.g. for-in and while 

let number = 10

if number < 10 
{
print (number is less than 10)
}
else if number > 100
{
print (number is greater than 100)
}
else 
{
print(“number is between 10 and 100 ”)
}

We can use optional binding in an if statement to check whether an optional contains a value. 

var optionalName:String ? = “Test”

if let tempStr = optionalName 
{
print “optional name is \(tempStr)”
}

if optional value is nil, the condition becomes false and won’t execute. 

We can use single if statement to bind multiple values. A where clause can be added to a case to further scope the conditional statement. In this case, if statement executes only if binding is successful for all of these values and all conditions are met. 

let optionalHello : “hello” 

let hello = optionalHello where hello.hasPrefix(“H”), let name = optionalName 
{
greeting = “\(hello), \(name)”
}

Switches are powerful, A switch statement can support any kind of data type and a wide range of comparison operations - it isn’t limited to integers and test for equality. 

let vegetable = “red pepper”

switch vegetable 
{
case “celery” : 
let vegetableComment = “Add some raisins and make ants on the log”
case “cucumber”, “watercress”:
let vegetableComment = “That would make good tea sanwitch”
case let x where x.hasPrefix(“bell”):
let vegetableComment = “Is it spicy \(x)?”
default:
let vegetableComment = “Everything tastes good in tea”
}

Notice that we don’t need to have a break here! 

References:

Sunday, October 4, 2015

Git tutorial - Undoing changes

Git revert command undoes a committed snapshot. But instead of removing the commit from the project history, it figures out how to undo the changes introduced by the commit and appends a new commit with the resulting content . This prevents git from losing the history. 

git revert

Git revert should be used if we want to revert entire commit from the project history. This can be useful for example when a bug was introduced by a particular commit. Instead of going ahead and fixing it manually, the revert command can be used to revert this change automatically. 

git revert undoes only the one commit that it is asked to revert. It does not revert all of the subsequent commit that occurred after this. In git, this is called git reset. in git terminology, git revert is a safe way to undo a change while git reset is a dangerous method. when reset is done, there is no way to get back the original content, it removes all of them permanently unlike revert. 

However, git reset is a versatile command in many ways. The git reset can be used to revert the changes in the staging area and the working directory. In other words, it should be only used to undo the changes in the local directory. 

Some of the usages for the command include the below 

git reset

This command removes the specified file from the staging area, but leaving the working directory unchanged. This upstages the file without overwriting any changes. 

git reset 

reset the staging area to match the most recent commit, but leaving the working directory unchanged. This upstages all files without overwriting any changes, giving the opportunity to re-build the staged snapshot from scratch. 

git reset —-hard 

resets the staging area and the working directory to match the most recent commit. In addition to upstaging the file, this —hard flag tells git to overwrite all the changes in the working directory too. In other words, it removes all the uncommitted changes too . to be used with caution 

git reset move the current branch tip backward to commit. resets the staging area to match, but leaving the working directory alone. All changes made since commit will reside in the working drirectory, which lets us to re-commit the project history using cleaner more atomic snapshots. 

another variant is git reset —hard



References:
https://www.atlassian.com/git/tutorials/undoing-changes/

Working With GCDAsyncSocket

One of the most powerful features of GCDAsyncSocket is its queued architecture. This allows to control the socket whenever it is convenient to the developer and not when the socket tells when it is ready. 

For e.g the below method will return immediately and the delegate method didConnectToHost:port: will be invoked when the connection has completed. 

[asyncSocket connectToHost:host onPort:port error:nil];

At this moment the connection is not yet established. It has internally just started the asynchronous connection attempt. However, AsyncSocket lets to reading / writing. Below method is going to queue the read request. After the connection is established, the read request will be automatically made. 

[asyncSocket readDataToLength:LENGTH_HEADER withTiemout:TIMEOUT_NONE tag:TAG_HEADER];

In addition to it, we can also do multiple read/write. 

[asyncSocket writeData:msgHeader withTimeout:TIMEOUT_NONE tag:TAG_HEADER];

//We don’t have to wait for the write to complete 

[asyncSocket writeData:msgBody withTimeout:TIMEOUT_NONE tag:TAG_BODY];


References: