Saturday, May 9, 2015

Free Hand Drawing on Google's Map View

Recently, I got a chance to work on a project, where we needed to provide an ability to users of an iOS app to draw on Maps. Basically, we decided to go with Google Maps, because of its overall coverage and its popularity. Hence, we used Google Maps SDK for iOS and we wanted to implement "Free Hand Drawing on the Google Maps".
To do so, I started searching around the internet for some good resources, but weren't able to find any good one that could just be used like Plug and Play. We had to do a lot of handling on our own and hence decided to write a blog post and a sample project just to make it useful for others, so that others in the same path don't struggle much like me.


If you are only planning to draw a Polygon on the Map (As most of them do), then may be you don't have to read the entire post. Instead just follow these steps:

(i) Copy & Paste these Folders into your project: "SARMapDrawView", "Categories" & "Models".

(ii) Since, "SARMapDrawView" is just a subclass of UIView, just initialise and place "SARMapDrawView" onto your View Controller     mapDrawView = [[SARMapDrawView alloc]initWithFrame:self.view.bounds];or if your using storyboard then just add an UIView to your controller and name its class to "SARMapDrawView".

(iii) Now, when you are ready to draw your polygon on the map, just call "enableDrawing" method on the view, now "SARMapDrawView" is in the Drawing mode, so if you just scribble or draw any shape with your finger on the map, it will explicitly draw a Polygon, by joining the Starting and the ending point of your touch. and you will receive the drawn Polygon(GMSPolygon) object in Block Callback ("polygonDrawnBlock") [Only if you are listening to it].


If you are too lazy like me who doesn't like following step by step guide like this, then just have a look into the Sample project on GitHub and i have done the same thing described above.


Also, don't forget to add the main dependency, Google Maps SDK to your project.
Here's the Reference to adding Google Maps iOS SDK to your project.
To get your API Key from Google to access their maps on your app.

Well, just following up with the above should get you up and running with drawing Polygons on the Google Maps View.




Oh, you're still reading this, then probably you're still interested in knowing about it works behind or just curious to know how well i am describing it.
Well, i would like to warn you before proceeding further. I am not very good at explaining things since it has been a long back that i have stopped writing.

If you're still On then let's not waste time and jump straight into the context.
For sure, I will make it as short as possible.


As I said before, "SARMapDrawView" is an UIView, which basically handles all the UITouch events that occurs on the screen and we have "GMSMapView" placed above it occupying the entire bounds of the view, which is again a subclass of an UIView and a main component of Google Maps SDK used to display the actual map.


So, Here we go...

We override all the UITouch event delegate methods in our subclass("SARMapDrawView") to detect user interaction with the view.
Once, our view is in drawing mode and the user interaction of map view is disabled, we start receiving touch events for our view. Once user taps on the view we receive the starting point in the "touchesBegan:withEvent:" delegate and store that point in the screen and when user drags his finger around the screen, we receive events and thus convert them to the points or so said coordinates of the screen or the Map view, since map view occupies the entire screen, as follows:


    CGPoint location = [touch locationInView:self.mapView];

Using this point/screen-coordinate, we can ask Google maps to provide us the Latitude and Longitude of that point by the following line:

    CLLocationCoordinate2D coordinate = [self.mapView.projection coordinateForPoint:location];


Now, we store these coordinates and when user drags along the screen, we need the user to give a feel of Free Hand Drawing. To do this we must draw Polylines with the received points/coordinates.

So, when the user drags his finger around the screen, we get consecutive  coordinates and we draw polylines in "touchesMoved:withEvent" method with the current coordinate and the previous coordinate, doing so whenever user moves his finger we receive the coordinates on the map view and thus draw a polyline on it. Refer "addCoordinate:replaceLastObject:inCoordinates" method for the drawing API's.

There is an issue when you draw Polylines in the Map View in this way:
The joint between the 2 polylines are not filled unless they are redrawn as a Single Polyline by giving out all the points/coordinates/path of those 2 polylines.

In our example, finally when user lifts up the finger, we draw the Polygon and thus we don't face the above issue, else it does looks cluttered(Unfilled Polylines, straight lines) when the Map view is zoomed in. So, in case of Polygon all the smoothing, filling, curving is done by the Google Maps SDK. 


Monday, April 20, 2015

Optionals in SWIFT

In SWIFT, an interesting and a powerful feature that i liked mostly is "Optionals".

Can you imagine, how many times you have checked a variable in Objective-C for its Validness, (If it is nil or not) ?
How many times do you think, you might have written the below code in Objective-C:

NSString *string = someFun()

if (string != nil){

//do some stuff with the returned string here

}


I can’t even count on this, since i do this often throughout my classes.


Apple have done a great job to solve this issue with Optional variables.


Let’s look into this feature more deeper with an example to understand its use and purpose.


Consider, you have an array of strings of Phone Numbers as below:
let numbers = [“9876543219”, “9898878890”, “9876556789”]


We’ll write a simple function to see if we can find a phone number within the array.



   func findNumber (number: String, numbers: [String]) -> String {

       for tempNumber in numbers {

           if ( tempNumber == number) {

               return number

           }

       }

   }



The above function takes in two parameters. A string and an array of strings.
The first parameter is the phone number we are looking for and the second parameter is an array of all the phone numbers. Then within the function we iterate over our array storing each phone number in a temporary variable called tempNumber. We then compare the values and if we find a match we return it. However, the above function is incomplete because we are only returning a value when one is found. What happens when we don’t find a value? We must return something. Ideally, we should return a nil but we specified String as our return type. One solution would be to return an empty string:

   func findNumber (number: String, numbers: [String]) -> String {

       for tempNumber in numbers {

           if ( tempNumber == number) {

               return number

           }

       }

       return ""

   }



The above solution is a failure because we should be able to use an if statement such as:

       if findNumber("9890878909", numbers: numbers) {

           numberFound()

       }



However, that if statement will never get executed because it always returns a String value. Moreover, it does not evaluate to a boolean expression. We could compare against an empty string but that defeats the purpose. It would be nice to return a nil when the phone number is not found in the array. Changing the last line to return nil will give us a compiler error because we set our return value to be a String. This is where optionals come in very handy.


An optional can have two states, a value or a nil. To declare an optional, simply suffix it with a ?. Let’s rewrite our function above to use an optional.

   func findNumber (number: String, numbers: [String]) -> String? {

       for tempNumber in numbers {

           if ( tempNumber == number) {

               return number

           }

       }

       return nil

   }



Now we are well equipped to use an if statement:

       let foundNumber = findNumber("9890878909", numbers: numbers)

       if foundNumber {

           numberFound()

       }



Now, let’s assume we needed to send the phone number to the “numberFound()” fun as “numberFound(number: Int)”. In that case, we cannot simply pass the constant “foundNumber”.

       if foundNumber {

           numberFound(foundNumber)

       }


Firstly, because foundNumber is a string and secondly because it is an optional. As i mentioned above that optionals can either contain a value or nil. When we created the constant foundNumber, it was implicitly defined as an optional too since that is the return type of our function.

       let foundNumber: String? = findNumber("9890878909", numbers: numbers)//Inferred type String?



It is important to understand that String and String? are not the same. The former can only contain a string whereas the later can contain either a string or a nil. So how do we convert the result of our function to the value of type String?. You can instruct the optional to provide you with a value if there is one.

       let foundNumber: String? = findNumber("9890878909", numbers: numbers)//Inferred type String?

       if foundNumber {

           numberFound(foundNumber!)//Note the use of the ! operator to unwrap the value to String

       }



We are not quite there yet because we need to send an Int to our sendNoticeTo function. Besides, we can also combine the two above statements into one:

       if let foundNumber = findNumber("9890878909", numbers: numbers) {

           numberFound(foundNumber.toInt())//Note the use of the ! operator to unwrap the value to String

       }



When used as an if let statement the constant foundNumber is assigned the actual value of type String, which is the same as unwrapping the value using a bang ! operator. Now that foundNumber is of type String we can call the toInt() function on it. There’s still one issue we haven’t addressed. The function toInt() returns Int? which is also an optional. Now we could nest if statements.

       if let foundNumber = findNumber("9890878909", numbers: numbers) {

           if let foundPhoneNumber = foundNumber.toInt() {

               numberFound(foundPhoneNumber)//Note the use of the ! operator to unwrap the value to String

           }

       }


Why nest when we can chain function calls. Swift provides what is called  "Optional Chaining" to make such statements compact:


           if let foundPhoneNumber = findNumber("9890878909", numbers: numbers)?.toInt() {

               numberFound(foundPhoneNumber)//Note the use of the ! operator to unwrap the value to String

           }


The above ties in very nicely because we chain the call to the function toInt() by using the ? operator. Since toInt() also returns an optional we can check to see if we received a valid phone number and then call the function “numberFound” else nothing will happen.

Sunday, April 19, 2015

Exploring SWIFT


Should have posted this a long back, but just got the perfect time to get it done. 

I got a chance to develop an e-Commerce mobile application targeted at iOS8. We decided to develop it using the latest technologies, so we chose to use the SWIFT language released by Apple in Conjunction with iOS8.


SWIFT is a safe, modern and powerful Language, it has a lot of interesting, time saving features, which could allow us(Developers) to focus/work more on the Application’s logic rather than the coding itself.


Swift’s shorthand syntax makes us to write less code when compared to Objective C.
It was a great decision to remove the semicolons(At the end of each statement), Braces (In Control Flows), Subscripts, Enumerations, etc…


Some of the very interesting stuff includes:
  • Optionals
  • Tuples
  • Closures
  • Access Control


Going briefly into those interesting stuff, that mostly adds value to our code/time.


Optionals:
The most interesting and powerful feature that we liked in Swift is “Optionals”. We can’t  imagine, how many times we have checked for nil value in Objective-C as given below.


NSString *string = someFun()
if (string != nil){
//do some stuff with the returned string here
}


SWIFT provides optional variables to solve this issue.


func findNumber (number: String, numbers: [String]) -> String? {
       for tempNumber in numbers {
           if ( tempNumber == number) {
               return number
           }
       }
       return nil
   }


        let foundNumber = findNumber("9890878909", numbers: numbers) //Inferred type String?


So, the “foundNumber” constant is inferred as optional and has a value or nil. To use its value, we need to use “!” operator to unwrap its value like this:
“foundNumber!”
It will return the value, if it has one or else the unwrapping would eventually fail.


Swift also provides Optional Chaining, which allows us to omit the chaining of function calls.
For Example:
           let foundPhoneNumber = findNumber("9890878909", numbers: numbers)?.toInt()



Tuples:
Tuples allows to bind two or more typed values organized into a single entity. We used that way to display appropriate messages for the HTTP Status code.
// tuple
let InvalidPasswordErrorCode = (401, "Invalid Password")
let InvalidEmailErrorCode = (404, "Invalid Email")
// show how to access the contents
//
let namedTuple (param1:Double, param2:String) = (402, “Some string here”)
// show how to acces the contents


Numerous times, we have worried for Methods in Objective-C not having Multiple Return Types. Tuples were introduced to solve such problems.


func MinusAndPlusValues(value:Double) -> (minus:Double, plus:Double) {
 return (value-10, value+10)
}
let minusPlus = MinusAndPlusValues(20.4)



Closures:
Closure is an inline-function or block of functionality that can be passed and used in your code. Closures in Swift are similar to the Blocks in Objective C.Just like blocks, it can capture and store the references of any constants & variables during which they are defined.
We used closures mostly as callback functions, when an API call returns a response.


           manager.registerUser(nameTextField.text, email: emailTextField.text, password: passwordTextField.text, zipcode: zipcodeTextField.text, success: { (responseObject:AnyObject!) in
               }
               }, failure: { (error:AnyObject!) in
          })




Access Modifiers:
This is a great addition to the Swift.
Swift provides 3 levels of access for the entities in the source code.
Public - Provides access to any class within or outside the module or framework.
Internal - Provides access to any class within or inside the module.
Private - Provides access only to the code inside the source file in which it is defined.


Example:
  • public class SomePublicClass {}
  • internal class SomeInternalClass {}
  • private class SomePrivateClass {}


The “SomePublicClass” can be accessed by any class from the project, “SomePrivateClass”, can be accessed only by the code inside the source file where this method is defined, whereas “SomeInternalClass” can be declared with or without the Access Modifier Level included, since “internal” access modifier is the default one.


Some other Interesting stuff Include:


Header Files:
Swift don’t have 2 different files for Header/Implementation, both are merged as one.
Coming from the Objective C background, it was hard to get rid of the Header Files, which was great at separating your declarations with the actual implementation, but overtime it did make sense, since most of the time, you don’t really need that stuff. it did reduce the useless declarations, thus getting rid of the redundant code.
Another really useful feature is that Swift won't ask you to import the header of any class to use the entities of that class. it just auto detects and imports them on its own, whenever you needed it.


Properties:
Another great feature is how Properties are used in Swift.
There are only 2 types: Constants & Variables, which are declared with “let” & “var” keywords.
Example:
Constant: let myConstant: Int = 20// Constant of type Int
Variable: var myVariable: String = “My Variable”// Variable of type String


You don’t have to declare or synthesize the properties, instead you just provide the access levels to access from other classes and use “self.” to access from the closures. That’s it.


Operating between Objective C & Swift:
It was a Wise/Necessary decision to provide interoperability between 2 languages for Apple’s Flagship devices. Meanwhile, it is also so simple to interoperate for the developers.
You just need to create a separate file (Even that is done by Xcode for you) that contains(Imported using the import keyword) the headers/names of the classes that needs to be interoperated that bridges between Swift & Objective C.


Conclusion:
Overall, it was a pleasing experience working with Swift.

Swift is still an evolving language and the changes are been added into it occasionally and hence the language remains incomplete in exploration.