Encore અંકુર PTL

Web and iPhone App Developer
follow me on twitter @ankurpatel

February 7, 2014 at 4:38pm

What I learned developing my first App for Mac OS X

I am an iOS Developer and have developed several apps for iPhone so I decided to create a Mac App for fun and to open source it for others to learn. 

Compared to iOS, there are very few examples and tutorials online teaching you how to write apps for Mac so I decided to make a simple Todo list app. The App is simple in that it allows users to enter todos to their list and check it when its complete. 

For the App I decided to use the principles I learned on iOS of using a table view where each table view cell contains a checkbox and textfield.

One thing I found different right away was that the table view in Mac Apps contained columns which is different from UITableView which only contains rows of UITableViewCell. Hence the datasource method signature is different in Mac where this method is called to get a NSView for a given row and column.

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row

Another thing I found difficult was the ability to rearrange rows in the NSTableView. First I searched on Google and Stackoverflow for some tutorials or sample code but there are very few projects and examples.

In iOS you just have to implement these two methods with relatively little code to get the rearranging functionality out of box.

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath

In Mac you have to implement these three methods and write a lot of logic code to handle the rearranging of the table view rows

- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation

- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation

- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pasteboard

I was not very impressed by this as the logic code to rearrange that could be written in iOS in just 4 lines of code is now 40 lines in Mac. I would imagine that Apple by now would have spent time to make some of the common use cases like these along with deleting a row item easier for developers to implement just like iOS.

What drew me to iOS was the ability to write less code especially when sticking with Apple’s user interaction guidelines and design patterns but I would not say the same for Mac App development.

The Todo list app source code is posted on Github if anyone is interested in reading the source code or enhancing the app by forking it: https://github.com/ankurp/Todo-List-for-Mac-OS-X

December 4, 2013 at 11:00am

How to add Apple’s Safari Web Push Notification to your Rails app

Few months ago Apple announced the release of their latest OS, Mavericks.

One of the major features was the ability to send push notifications to Macs similar to iOS. These notifications like iOS Push Notifications can be customized with your website logo, message and action.

image

Setup

To setup push notification, add the Web Push Notification Rails gem to Gemfile and bundle install.

gem 'web-push-notification-rails'
bundle install

Once the gem is installed you need to download the proper certificates and save it in your Rails app. Create a cert folder inside of your Rails app root and store the certificates generated from the steps below here.

P12 certificate

This the first of 2 certificates you need to sign. Apple has a step-by-step for most of it. You can pick up from step 7. Alternatively, you can follow all of my steps:

  1. Go to iOS Provisioning Portal (you need to login or register)
  2. Click on "Website Push IDs" on the left side menu
  3. Click on "New Website Push ID" and fill in the 2 fields
  4. After you come back to the listing of website push ids, select the created Push Id and click on "Edit" and then "Create Certificate…"
  5. Follow the steps on About Creating a Certificate Signing Request (CSR)
  6. Once you download the Certficate.cer, double-click to install
  7. In the “Keychain Access” tool right-click on Website Push ID: and select both and right click "Export 2 items…
  8. Change “File Format” to “Personal Information Exchange(.p12)” and save (preferably to Rails.root/cert/)
  9. The password you enter during the saving process will go into the initializer (“Run Generator” step)

WWDR Certificate

Second certificate you need to sign the web package

  1. Download http://developer.apple.com/certificationauthority/AppleWWDRCA.cer
  2. Double-click to install
  3. In the “Keychain Access” tool right-click on “Apple Worldwide Developer Relations Certification Authority” and click on Export “Apple….
  4. Change “File Format” to “Privacy Enhanced Mail (.pem)” and save it (preferably to Rails.root/cert/)

Run generators

Last password parameter is optional. You can just edit the initializer later

   rails g web_notification:notification_package website_name website_service_url website_push_id website_allowed_domain website_url_formatted_string wwdr_certificate_path key_path [cert_password]

Example:

   rails g web_notification:notification_package mixtapp https://www.mixtapp.co web.com.encoredevlabs.mixtapp https://www.mixtapp.co "https://www.mixtapp.co?%@" cert/AppleWWDRCA.cer cert/website_aps_production.cer.p12 password

If password is blank do not enter the last parameter.

Customize

If you need to change the password or location of the certificates later you can change it in the web_notification_package_initializer.rb file.

The package sent to Apple is inside notfication/web_package folder in Rails.root. Customize the icons inside icon.iconset folder. You can also customize the website.json which was genereated using the values specified in the generator. Checkout the Apple documentation link to see what values you need to set in the json file.

Apple Callback to Controller

All request from Apple regarding the web package will be sent to apple_web_notifications_controller.rb which you can customize or you can change the generated routes in the routes.rb file and send the Apple callback methods to your desired controller.

You will need to implement what needs to be done once you get the device token from Apple.

Sending Push notification

Currently the gem doesn’t provide functionality to send push notification message so to test sending notification use a gem called Houston. Once installed you can send push notifications by running the following command. Change the device token along with the certificate path and make sure to run in production environment as it only works in Production.

  apn push "64BE8308E51B6B91C0D41A8C856274977A6A45650049435C02F5E9944AB9D7F7" -c cert/apple_push_notification.pem -e production -P "{\"aps\":{\"alert\":{\"title\":\"Title test\",\"body\":\"Body test\"},\"url-args\":[\"someparams\"]}}"

Notes

You will need SSL certificate to make this work and if you want to try it for free you can get a trial SSL certificate for your server through Comodo.

Also you will need to send push notification to production APNS rather than sandbox.

Checkout the Apple WWDC Session Video if you want detailed overview on how the Safari push notifications work. 

If you want to contribute to this Gem, submit a pull request.

November 13, 2013 at 4:04pm

at command to schedule tasks

Recently came across a command in Unix like systems called

at

This command executes any command given at the specified date time. Here is an example

at takes time and data as parameter so if you want to run a task at midnight on Dec 25th you can run

at midnight Dec 25

followed by the command you want to run and end it by pressing Control-D.

If you specify just time it will try to execute that command at that time today. If the time is past the current time today then it will execute it tomorrow at that time. For example if you run a command at 3pm and it is 1pm currently then the command will run 2 hours later but if it is 5pm then it will run at 3pm next day.

Alternately you can pass a file and write commands to that file that you want to run and pass that. Benefit of doing this is that you can keep appending or changing the task file and it will run all the commands in that file.

The command runs the task only once so to keep running it periodically you need to run the command again or you can run it as the very last task in the task file and the command will then execute at the time specified the next day.

This command might be useful to some who do not want to setup cron jobs on the server. If you have multiple servers, it might be helpful to have your web application run this command on the machine it runs and it will give you the functionality of scheduled tasks without the hassle of synchronizing the crontab file across all servers.

September 17, 2012 at 1:32am

Passing Arguments in JSONP callback

It is not possible to pass arguments in your JSONP callback function directly currently as the callback function is invoked with only one argument and that is the response from the server. To solve this problem there is a hack in javascript you can do to pass arguments to your callback function.

First lets review functions and their scope. Any function you create using the syntax below can be invoked by just calling the someFunc() or window.someFunc() since the function is part of the global scope and all global variables and functions are attributes of the window object.

function someFunc() { /*Your Code*/ };

Now knowing this you can create bunch of functions with dynamic names by just indexing window object with a callbackName that we are generating here using a globalCounter.

var globalCounter = 0;
var callbackName = 'callback_' + globalCounter++;
window[callbackName] = function(response, args) { /* your code */ }

Using closure you can call the real callback which takes one extra argument along with the response:

function jsonpOneArg(realCallback, arg) {
    var callbackName = 'callback_' + globalCounter++;
    window
[callbackName] = function(response) {
        realCallback(response, arg);
        delete window[callbackName];
    };
   
return callbackName;
}

Now you can call jsonpOneArg() with your real callback and argument and it will return a string version of the callback functions name which you can use as your jsonp callback. Now when the server responds it sends just the response to your callback function called “callback_0” and because in its scope it has a pointer to the real callback it will invoke that function with the argument you passed.

September 14, 2012 at 3:01am

Web Inspector Debugging for iPhone and iPad from Mac OS X

Now you can inspect DOM elements, profile Javascript/CSS and debug on iPhone/iPad using the latest iOS 6 iPhone and iPad simulator along with the latest Safari 6.

To get started you need the latest version of Xcode 4.5 to run iOS 6 on the iPhone and iPad simulator and Safari 6 installed on your Mac. Currently Safari 6 is available for Lion and Mountain Lion.

Once you have the iOS 6 simulator and Safari 6 installed and running, click on the Develop menu of Safari 6 and you should now see iPhone Simulator or iPad Simulator menu item listing all the webpages that are available to debug in Mobile Safari via Safari 6 Web Inspector. You will also see native apps show up in this menu item if the application is running and you can debug UIWebView using this method as well.

With the latest Web Inspector you can change css properties on the fly just like you can on desktop browser and can profile Javascript and CSS along with seeing the network traffic. Plus you can put break points in your Javascript code and inspect variables and use the Javascript console to try out code changes.

June 1, 2011 at 8:28am

iNote - Sketch and Share for iPhone, iPod touch, and iPad on the iTunes App Store →

Its on the App Store for download!!!

May 15, 2011 at 3:53pm
(via iGarbagePlateFinder for iPhone, iPod touch, and iPad on the iTunes App Store)

(via iGarbagePlateFinder for iPhone, iPod touch, and iPad on the iTunes App Store)

April 3, 2011 at 6:02pm
(via Teams in a race to develop Web concepts at RIT48 | Democrat and Chronicle | democratandchronicle.com)

(via Teams in a race to develop Web concepts at RIT48 | Democrat and Chronicle | democratandchronicle.com)

March 19, 2011 at 3:52pm
Holi!

Holi!

March 11, 2011 at 1:49am
One day&#8230;

One day…