My experience with Mobile App Development - GPS Treasure Hunt Game

Shawn Rebello

The Idea

I had just started learning the Ionic Framework for cross platform mobile app development by building demo apps to learn how certain native features work and/or reading Josh Morony's tutorials  when I found this xkcd  on a  reddit post  and it gave me an idea.
What better way to learn a framework than to dive in and build a project?
Besides, on days when I do not have college,  I could continue coding till 3 am.

Development Begins

So I create a new Ionic 2 project and decide to go with a tabs layout and start with the GPS features which I believe (incorrectly) would be the hardest part of the app.


Few hours into the project and the geolocation features where the easiest to add.
 Lucky for me my development machine (Macbook Air) has a GPS receiver and so I'm able to test the location features directly through the browser.

I also manage to add typescript functions to calculate distance between two gps coordinates with Haversine's formula and test the first iteration of the app on a local device.
On noticing the wildly inaccurate distances I realized that GPS is horribly inaccurate within a building , enough to locate the house but with rapidly changing values, off by at least 20-30 meters.

Now that the GPS functionality was added I tried to think of a way to transfer the GPS location from one app user to another, without them having to manually copy paste any data. 
I could make a backend server with Rails and connect it to the app, but that would incur hosting costs.

So a few days later I get the idea to use either deep links or barcodes to allow transferring the data between users, and also encrypt the data so that the average user does not decode the barcode and find the location.

2:39 am and I get the geolocation working!
Development was paused  for the next week and when I resumed I realized that  the Ionic Native barcode scanner as well as cordova barcode scanner allow scanning from camera only not the gallery, guess I hadn't thought this through.

After trying on many solutions, involving plugins not included into Ionic Native I finally got it working using the the port of zxing with the html canvas element and getting the images with cordova imagepicker.

Now that I could finally scan barcodes from gallery within the Ionic 2 app, I had to just implement the media sharing feature and I could then relax and focus on the UI, but that took a bit longer than expected.

The Canvas.decode function nested inside the ImagePicker kept on failing and multiple solutions to get it working failed, until I finally found out the issue:
the scope of this was changed and that's why Canvas couldn't be used.
So I assign this to another variable and manage to get it working again


      ImagePicker.getPictures(options).then((results) => {
        for (var i = 0; i < results.length; i++) {
          var tempObj= this;
          tempObj.convertImgToBase64URL(results,function(base64Img){


Now that all the main functionality was done I could focus on the UI so I write a function in the provider to dynamically generate a color code based on the percentage of distance covered and use it in the view.
A cup of coffee and some scss later I've got the app ready for deployment

Android 6.x.x issues with Ionic 2


So all this while I was using the browser to test the non-native stuff and the spare device to test the native features, the app worked perfectly on that phone (android 4) and I assumed it would work on later versions as well.

But I had some issues with the runtime permissions on Android 6.x.x.
Installing Ionic native diagnostic plugin raised some 'Unmet Peer Dependency Warning' , so I decided to give the cordova diagnostic plugin a try instead which worked like a charm.

Release

Designed an icon, splashscreen and created app intro slides with photoshop.
Tested the app on an emulator running Android 6 and then pushed it to the play store.

You can check it here at: https://play.google.com/store/apps/details?id=com.shawnrebello.hotorcold251239 and leave me a feedback in the comments.

A few screens:








Thanks for reading this and have a great day!

Fixing the "URI signature match failed" error while displaying Reddit Images

Shawn Rebello

While trying to pull images from Reddit using its json API for an app I ran into a strange error,
Using the extracted image url, a few images would load perfectly but others would fail.

Solution

Digging a little deeper, it is clear that the image url  supplied by the reddit api is incorrect. Attempting to open the url in the browser gives the error:
URI signature match failed.

Consider the following url supplied by reddit:


Replacing the & amp ; with a & will return the correct image url.


*As of 14-2-2017, this issue still persists.

So this can be fixed by replacing all instances of & with & which can be done with regex in all most every language.
Since I'm working with Angular at the moment, I wrote a simple ts fix:


 let oldURL: string = "https://i.reddituploads.com/3ac211e88e214eff9113fa4ed2f3635e?fit=max&h=1536&w=1536&s=b545edd8de65c9bb18bcca7d38aad0b7";
 let newURL: string = oldURL.replace(/&/g,"&");


Note the g after /&/ that is to make sure multiple occurrences of the string matching are replaced.
Hope this helps!

Rails method arguments: has_many and belongs_to

Shawn Rebello
  If you are used to C/C++/Java , then you would be call a method create_user(), with a parameter "Shawn" using:


create_user("Shawn")

In Ruby parenthesis are optional and this give us cleaner function calls like:

create_user "Shawn"

Consider the methods has_many and belongs_to



belongs_to :author
has_many :pages

A lot of beginners may not realize that the belongs_to :author is just a method call with a symbol as a parameter.
It could have also been written like this:



  belongs_to(:author)
  has_many(:pages)

Alternatively, you could also use a string and pass it as a symbol:



  belongs_to "author".to_sym
  has_many "pages".to_sym

Or..


  belongs_to "author".intern
  has_many "pages".intern


As you can see there is no Rails magic involved, it is just that the creator of Rails decided to go with this syntax.
Also the Rails community prefers to use symbols over strings for internal identifiers.
To know the benefits of this approach you can check out this thread.

Hope this helped you!

Drop a comment if you have any questions.

How is Rails able to find the plural of words while generating scaffolds or controllers?

Shawn Rebello
Take a look at the picture below, nothing complex just a regular scaffold command.

Ruby on Rails Pluralize example
The selected text shows the pluralized version of Record
 As you can see, Rails has automatically pluralized names for views, resource routes, controllers etc, but has not pluralized the model name.

Ever wondered how Rails finds the plural of words while creating controllers, scaffolds, class names etc?

Enter The Inflector..

A module in the ActiveSupport class,  ActiveSupport::Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without, and class names to foreign keys.

The default inflections for pluralization, singularization, and uncountable words are kept in inflections.rb.


But what if I don't want the default pluralizations?


Say you want to make a scaffold GunLaws;
 What if you want the model to remain plural and Rails wants to call it GunLaw?

Using rails g scaffold -h we see this option:


[--force-plural], [--no-force-plural]

Neat! So we can use:


rails g scaffold GunLaws --force-plural

Final thoughts

We can also edit  inflections.rb file under config/initializers/inflections.rb
ActiveSupport::Inflector.inflections do |inflect|

  inflect.uncountable %w(gun_laws)

end


For more info take a look at the documentation here

Leave a comment if this helped you or if you have any questions!

Difference between require, include and load in Ruby on Rails

Shawn Rebello
  Splitting code into several files allows us to reuse code and conform to the DRY principle.  To do this we may have to use require, include or load statements in our file.
 The differences between them are subtle and confusing, so I will make an attempt to explain:

load

The load method reads and parses another files into your code every time a script is executed.

For example,  if we have some module in one file..

sum_module.rb


module SumModule
  def yolo
    # ...
  end
end

sum_class.rb


load 'sum_module.rb'
class SumClass

  # ...
end

...then we can use the load 'sum_module.rb' just before the class definition in sum_class.rb file to get the access to yolo function contained in our module.


require

This method reads the file from the file system, parses it, saves to  memory and runs it in place. 
Simply put, even if you were to change the required file when the script is running, those changes will not be applied; Ruby will use the file in memory, not the original file from the file system.

Also, there is no need to specify the “.rb” extension of the library file name.
It is similar to load but will load the file only ONCE!
It keeps track of whether a library was already loaded or not. 


Q: Why would we ever need to use load instead of require?
A:   Use load when your modules changes frequently  and you  want to pick up these changes in classes that load these modules.

include


When you include a module into your class  it is as if you took  code defined within a module and inserted it within the class, where you ‘include’ it.

The Ruby include is nothing like the C include. The Ruby include statement "mixes in" a module into a class. It's a limited form of multiple inheritance.
On the other hand include in C language replaces the #include line, by the content of the file. Included files don't have to be 'header' and #include don't have to be at the beginning of file but can be anywhere, like in class or even a method definition.

Hope this helped you! 
Drop a comment if you have any questions.