<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Devgirls Weblog</title>
	<atom:link href="http://devgirl.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://devgirl.org</link>
	<description>Trials and tribulations of software development...</description>
	<lastBuildDate>Fri, 10 May 2013 18:13:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>JavaScript Frameworks Session Resources &#8211; Adobe MAX 2013</title>
		<link>http://devgirl.org/2013/05/10/javascript-frameworks-session-resources-adobe-max-2013/</link>
		<comments>http://devgirl.org/2013/05/10/javascript-frameworks-session-resources-adobe-max-2013/#comments</comments>
		<pubDate>Fri, 10 May 2013 15:58:50 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Adobe MAX]]></category>
		<category><![CDATA[HTML/JS]]></category>
		<category><![CDATA[AngularJS sample application]]></category>
		<category><![CDATA[comparing JavaScript MVC frameworks]]></category>
		<category><![CDATA[Ember.js sample application]]></category>
		<category><![CDATA[JavaScript Frameworks]]></category>
		<category><![CDATA[JavaScript Frameworks comparison]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=5308</guid>
		<description><![CDATA[If you attended our JavaScript Frameworks session at Adobe MAX 2013 and would like the session resources, you can find them here: 1) The presentation slides 2) The AngularJS sample Wine Cellar application 3) The Ember.js sample Wine Cellar application Also see Christophe&#8217;s blog for the links to his github account where you can find [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://devgirl.org/wp-content/uploads/2013/05/comparing.jpeg"><img src="http://devgirl.org/wp-content/uploads/2013/05/comparing.jpeg" alt="comparing" width="300" height="200" class="alignleft size-full wp-image-5316" /></a></p>
<p>If you attended our JavaScript Frameworks session at Adobe MAX 2013 and would like the session resources, you can find them here: </p>
<p>	1) The <a href="http://devgirl.org/files/MAX-2013/">presentation slides</a><br />
	2) The <a href="https://github.com/hollyschinsky/angular-cellar-basic">AngularJS sample Wine Cellar application</a><br />
	3) The <a href="https://github.com/hollyschinsky/wine-cellar-ember">Ember.js sample Wine Cellar application</a></p>
<p>Also see <a href="http://coenraets.org">Christophe&#8217;s blog</a> for the links to his github account where you can find the Backbone.js and jQuery Mobile versions of the wine cellar applications.</p>
<p>Thanks so much to everyone that attended (especially since it was 8am after the MAX Party <img src='http://devgirl.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) &#8211; we hope it was worth your while <img src='http://devgirl.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>I will post the link to the session recording for anyone else interested as soon as I can find that as well&#8230;</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2013%2F05%2F10%2Fjavascript-frameworks-session-resources-adobe-max-2013%2F&amp;title=JavaScript%20Frameworks%20Session%20Resources%20%E2%80%93%20Adobe%20MAX%202013" id="wpa2a_2"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2013/05/10/javascript-frameworks-session-resources-adobe-max-2013/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Fun with AngularJS!</title>
		<link>http://devgirl.org/2013/03/21/fun-with-angularjs/</link>
		<comments>http://devgirl.org/2013/03/21/fun-with-angularjs/#comments</comments>
		<pubDate>Thu, 21 Mar 2013 14:55:20 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[angularJS]]></category>
		<category><![CDATA[angularJS itunes]]></category>
		<category><![CDATA[angularJS overview]]></category>
		<category><![CDATA[angularjs phonegap]]></category>
		<category><![CDATA[angularJS sample]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=5195</guid>
		<description><![CDATA[ecently AngularJS, an MVC style JavaScript framework from Google, has been gaining more momentum. I&#8217;ve been curious about it for awhile and when I read this article recently, I decided it was finally time to give it a whirl. I was pleasantly surprised with what I found. I first watched these two videos by John [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://devgirl.org/2013/03/21/fun-with-angularjs/angular-logo/" rel="attachment wp-att-5266"><img src="http://devgirl.org/wp-content/uploads/2013/03/angular-logo-150x150.jpeg" alt="angular-logo" width="150" height="150" class="alignleft size-thumbnail wp-image-5266" /></a><span class='et-dropcap' style="font-size: 60px; color: #9b9b9b;">R</span>ecently <a href="http://angularjs.org/">AngularJS</a>, an MVC style JavaScript framework from <a href="http://google.com">Google</a>, has been gaining more momentum. I&#8217;ve been curious about it for awhile and when I read <a href="http://net.tutsplus.com/tutorials/javascript-ajax/3-reasons-to-choose-angularjs-for-your-next-project/">this article</a> recently, I decided it was finally time to give it a whirl. I was pleasantly surprised with what I found. I first watched these two videos by <a href="http://johnlindquist.com/">John Lindquist</a> which I highly recommend as a starting point to get your feet wet. They are short and totally worth the time:</p>
<ol>
<li><a href="http://www.youtube.com/watch?v=WuiHuZq_cg4">Simple ToDo&#8217;s App </a> </li>
<li><a href="http://www.youtube.com/watch?v=IRelx4-ISbs">Simple Twitter Search App</a>  </li>
</ol>
<p>Part of the reason I personally may have been hooked initially could be due to my <a href="http://www.adobe.com/products/flex.html">Adobe Flex</a> background. There&#8217;s a reminiscent feel with AngularJS to Flex in the two-way binding, HTML extension etc so I could see how a lot of Flex developers might feel at home with this framework. The framework is built on the idea that <a href="http://en.wikipedia.org/wiki/Declarative_programming">declarative programming</a> should be used for building the UI and <a href="http://en.wikipedia.org/wiki/Imperative_programming">imperative programming</a> for your business logic. With AngularJS you can do quite a bit with a small amount of code due to the built-in features that will be explained further in this post. It also relies on <a href="http://docs.angularjs.org/guide/di">dependency injection</a> throughout as well as the separation of the model/view/controller. Here&#8217;s a nice illustration from the <a href="http://docs.angularjs.org/guide/concepts">AngularJS site</a> that helps explain more:</p>
<p><a href="http://devgirl.org/2013/03/21/fun-with-angularjs/concepts-controller/" rel="attachment wp-att-5231"><img src="http://devgirl.org/wp-content/uploads/2013/03/concepts-controller.png" alt="concepts-controller" width="463" height="316" class="aligncenter size-full wp-image-5231" /></a></p>
<div class='et-learn-more clearfix'>
					<h3 class='heading-more'><span>Disclaimer</span></h3>
					<div class='learn-more-content'>My intention is not to incite a frameworks war here. I know there are a myriad of JavaScript frameworks available that people are passionate about. I&#8217;m simply sharing my thoughts and observations <img src='http://devgirl.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</div>
				</div>
<p>After watching the videos above, I moved on to <a href="http://docs.angularjs.org/tutorial">the tutorial</a>, which was very easy to follow and I thought it was especially cool how they introduced testing your AngularJS app while building it using <a href="http://pivotal.github.com/jasmine/">Jasmine</a> and <a href="http://karma-runner.github.com/0.8/index.html">Testacular</a>. I had previously only heard of those but got a much better idea of how to use them from the tutorial. It&#8217;s obvious they kept testing in mind while creating this framework. </p>
<p>I then decided to build myself <a href="http://devgirl.org/files/MediaExplorer">a web application</a> with what I had learned. I&#8217;m a big music fan, always downloading from iTunes for my running playlists etc, so I thought I&#8217;d build a simple web app that interfaced with the <a href="http://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html">iTunes Search API</a>. The resulting application is <a href="http://devgirl.org/files/MediaExplorer">here</a>. You can grab the project from <a href="https://github.com/hollyschinsky/MediaExplorer">my github account here</a>. This was my first newbie attempt so I&#8217;m open to critique and feedback on how I could make it better. I noticed there are often multiple ways to do the same thing using AngularJS, so I&#8217;m still in the learning process of when to use what. Overall though I was impressed by how fast I was able to make it all work and how much the framework provides for you. From my <a href="http://devgirl.org/files/MediaExplorer">Media Explorer</a> application you can enter a search term for anything media related (artist, song name or part, video etc). Once you get the results back, try out the sort and filter to see the returned results sort and filter accordingly. The filter field will filter results as you type into it. This is all built into the <a href="http://docs.angularjs.org/api/ng.filter:filter">array filtering mechanism</a> in AngularJS. Currently the max number of results returned defaults to 50. </p>
<p><a href="http://devgirl.org/2013/03/21/fun-with-angularjs/screen-shot-2013-03-20-at-10-59-23-pm-3/" rel="attachment wp-att-5280"><img src="http://devgirl.org/wp-content/uploads/2013/03/Screen-Shot-2013-03-20-at-10.59.23-PM2.png" alt="Screen Shot 2013-03-20 at 10.59.23 PM" width="680" height="314" class="aligncenter size-full wp-image-5280" /></a></p>
<p>Hitting the play button on the far left of any row will bring up an overlay to play the sample media as shown below:</p>
<p><a href="http://devgirl.org/2013/03/21/fun-with-angularjs/screen-shot-2013-03-20-at-11-33-26-pm-2/" rel="attachment wp-att-5281"><img src="http://devgirl.org/wp-content/uploads/2013/03/Screen-Shot-2013-03-20-at-11.33.26-PM1.png" alt="Screen Shot 2013-03-20 at 11.33.26 PM" width="664" height="374" class="aligncenter size-full wp-image-5281" /></a></p>
<div class='et-box et-info'>
					<div class='et-box-content'>I used <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a> in my <a href="https://github.com/hollyschinsky/MediaExplorer/">MediaExplorer</a>, but subsequently found <a href="http://angular-ui.github.com/">AngularUI </a>and <a href="http://angular-ui.github.com/bootstrap/">Angular Bootstrap</a> which you should also check out for help with your UI specific to Angular.</div></div>
<p>In the next sections I&#8217;ll cover some of the main AngularJS concepts that seem important to understand.</p>
<h3>Data Binding</h3>
<p>One of the first things I was most excited to see with AngularJS is that it has built-in support for two-way data binding similar to Flex (yay)! This is a big deal for data-driven applications in particular and can save you a TON of time coding. Below are two images from the AngularJS site that I think illustrate this point so well:</p>
<p><img src="http://docs.angularjs.org/img/One_Way_Data_Binding.png" width="400" height="255" class="aligncenter" /><br />
<img src="http://docs.angularjs.org/img/Two_Way_Data_Binding.png" width="400" height="290" class="aligncenter" /></p>
<p>If you want to try a very basic example of the two-way data binding in action, I found <a href="http://embed.plnkr.co/dECGEtvMvcMwabCP1IoZ/preview">this live sample here</a>. If you look at the source code you&#8217;ll see how simple it is:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div&gt;
    Binding the value in the text field to the model name.
    &lt;br/&gt;&lt;br/&gt;
    &lt;input type=&quot;text&quot; ng-model=&quot;name&quot; placeholder=&quot;Enter a name here&quot;/&gt;
    &lt;span ng-show=&quot;name&quot;&gt;&lt;h4&gt;Hello {{name}}&gt;&lt;/h4&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>
<p>As you type into the input field it will show up next to the &#8216;Hello&#8217; string since the <em>name</em> field is referenced there and is also the bound model object on the HTML input (with <em>ng-model=&#8221;name&#8221;</em>). </p>
<h3>Model</h3>
<p>The model is simply a plain old JavaScript object, does not use getter/setter methods or have any special framework-specific needs. Any changes are immediately reflected in the view via the two-way binding feature. There&#8217;s a concept of scope in the AngularJS framework, where all model objects stem from. I recommend seeing the <a href="http://docs.angularjs.org/api/ng.$rootScope.Scope">AngularJS Scope documentation</a> for more information on this topic. Typically your model objects are initialized in your controller code with syntax like: </p>
<pre class="brush: jscript; title: ; notranslate">
$scope.searchTerm = &quot;Alicia Keys&quot;;
</pre>
<p>But in the HTML template, that model variable would be referenced in curly braces such as: {{searchTerm}} without the <em>$scope</em> prefix.</p>
<h3>View</h3>
<p>The view is the rendered HTML that contains the transformed DOM resulting from a combination of the HTML template along with the AngularJS model and controller. The AngularJS View is aware of the controller and model, and accesses it through annotated HTML directives specific to AngularJS. For example, an <a href="http://docs.angularjs.org/api/ng.directive:ngClick">ng-click</a> AngularJS <a href="http://docs.angularjs.org/guide/directive">&#8216;directive&#8217;</a> can be applied to a button element to call a specific method in the controller when clicked. More on directives below&#8230;</p>
<h3>Controller</h3>
<p>The controller is used to provide the business logic behind the view and construct and value the model. The goal is to not manipulate the DOM at all in the controller, which is something to get used to if you&#8217;ve been using other frameworks. </p>
<h3>Filters</h3>
<p><a href="http://docs.angularjs.org/api/ng.$filter">AngularJS filters</a> are used to modify data in some way, similar to formatters in Flex. For instance, a built-in filter called <em>uppercase</em> would look like this when applied to the name string from the model in order to uppercase it upon display.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;td&gt;{{name|uppercase}}&lt;/td&gt;
</pre>
<p>You&#8217;re welcome to write your own filters as well. I included a custom one for fun in my application called <em>capitalize</em> that will simply capitalize the first letter of a string. </p>
<pre class="brush: jscript; title: ; notranslate">
mediaApp.filter('capitalize', function() {
    return function(input, scope) {
        if (input!=null)
            return input.substring(0,1).toUpperCase()+input.substring(1);
    }
});
</pre>
<p>You can see it applied here:<br />
<a href="http://devgirl.org/2013/03/21/fun-with-angularjs/screen-shot-2013-03-20-at-10-58-35-pm/" rel="attachment wp-att-5250"><img src="http://devgirl.org/wp-content/uploads/2013/03/Screen-Shot-2013-03-20-at-10.58.35-PM.png" alt="Screen Shot 2013-03-20 at 10.58.35 PM" width="680" height="393" class="aligncenter size-full wp-image-5250" /></a></p>
<p>There&#8217;s also an array filtering feature which is really cool, and you can see an example of it in the <a href="http://devgirl.org/files/MediaExplorer">Media Explorer</a> app. When you specify a filter string on an array in the Angular <a href="http://docs.angularjs.org/api/ng.directive:ngRepeat">ng-repeat</a> directive it will automatically filter the matching results into a new array. </p>
<p>For instance, here&#8217;s the code from the Media Explorer that specifies the <em>filterTerm</em> (the model object bound to the filter input HTML element) to your results list as you type (automatically applied do to the two-way data binding on the model data):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;label&gt;Filter by
     &lt;input type=&quot;text&quot; ng-model=&quot;filterTerm&quot; class=&quot;input-small&quot;/&gt;
&lt;/label&gt;
...
&lt;tr ng-repeat=&quot;item in mediaResults | filter:filterTerm | orderBy:sortProp&quot;&gt;
     &lt;td&gt;&lt;button id=&quot;playBtn&quot; class=&quot;btn&quot; ng-click=&quot;playVideo(item)&quot;&gt;&lt;i class=&quot;icon-play&quot;&gt;&lt;/i&gt;&lt;/button&gt;&lt;/td&gt;
     &lt;td&gt;&lt;a href=&quot;{{item.previewUrl}}&quot;&gt;&lt;img ng-src=&quot;{{item.artworkUrl60}}&quot;&gt;&lt;/a&gt;&lt;/td&gt;
     &lt;td&gt;{{(item.trackName != null) item.trackName || item.collectionName}}&lt;/td&gt;
     &lt;td&gt;{{item.kind | capitalize}}&lt;/td&gt;
     &lt;td&gt;{{item.artistName}}&lt;/td&gt;
     &lt;td&gt;{{item.collectionName}}&lt;/td&gt;
     &lt;td&gt;{{item.trackPrice}}&lt;/td&gt;
     &lt;td&gt;{{item.collectionPrice}}&lt;/td&gt;
     ...
</pre>
<h3>Directives</h3>
<p>Directives are ways to transform the DOM through extended HTML. The add additional behavior. If you happen to have done Flex, it&#8217;s similar to adding a property like <em>itemRenderer</em> to an MXML component, or specifying <em>click</em> to call a function. In AngularJS there are a bunch of built-in ones you can use, most with a prefix of <strong>&#8216;ng&#8217;</strong> <em>(ng-click, ng-show, ng-change, ng-app</em> etc). They&#8217;re actually defined with camelCase in the JavaScript, but applied with a dash to the HTML. You can also define your own directives and apply them in a similar fashion. In my <a href="http://devgirl.org/files/MediaExplorer/#/">Media Explorer</a> application I wrote a <a href="https://github.com/hollyschinsky/MediaExplorer/blob/master/js/directives.js">couple of directives</a> you could see for more examples. I used them to manipulate DOM elements since it&#8217;s not good practice to do so in the controller code. One called <em>videoLoader</em> is used to play and stop the video in the modal when the play button is clicked:</p>
<pre class="brush: jscript; title: ; notranslate">
mediaApp.directive('videoLoader', function(){
    return function (scope, element, attrs){
        console.log(scope.url);
        scope.$watch(&quot;url&quot;,  function(newValue, oldValue){ //watching the scope url value
            element[0].children[0].attributes[3].value=newValue; //set the URL on the src attribute
            element[0].load();
            element[0].play();
        }, true);
        scope.$watch(&quot;showFlag&quot;,  function(newValue, oldValue){
            if (!newValue) // if the showFlag is false, stop playing the video (modal was closed)
                element[0].pause();
        }, true);
    }
});
</pre>
<p>Then to apply this videoLoader directive to my video control, I add it as an attribute with a dash, such as:</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;video id=&quot;vid&quot; width=&quot;320&quot; height=&quot;240&quot; video-loader=&quot;item.previewUrl&quot; autoplay controls&gt;
     {{url}}
     &lt;source id=&quot;vidsrc&quot; ng-src=&quot;url&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;
</pre>
<h3>Services</h3>
<p>Services are provided in AngularJS to help you do common task. For instance, there&#8217;s a built-in <strong><a href="http://docs.angularjs.org/api/ng.$http">$http</a></strong> service that gives you access to make http or JSON requests etc, there&#8217;s also a <strong><a href="http://docs.angularjs.org/guide/dev_guide.services.$location">$location</a></strong> service that gives you access to the browser location URL and helps you parse it etc. There are a bunch of others built-in and once again you can also write your own. You may write your own in the case where there&#8217;s something you know you&#8217;re going to use more than once in your application. In my application I did write <a href="https://github.com/hollyschinsky/MediaExplorer/blob/master/js/services.js">a service</a> just to try it out and use it to call the iTunes API with the <strong><a href="http://docs.angularjs.org/api/ngResource.$resource">$resource</a></strong> service, which allows you to interact with RESTful services and provides higher level behavior over the <strong>$http</strong> service (but is dependent on the <strong>$http</strong> service). My service looks like this:</p>
<pre class="brush: jscript; title: ; notranslate">
mediaApp.factory('MediaService', function($resource){
    return $resource('https://itunes.apple.com/:action',
        {action: &quot;search&quot;, callback: 'JSON_CALLBACK'},
        {get:  {method: 'JSONP'}
    });
});
</pre>
<h3>Routes</h3>
<p>You  typically configure routes in your main or app.js file for an AngularJS app. For instance, mine is very basic since I&#8217;m not using multiple views and looks like this:</p>
<pre class="brush: jscript; title: ; notranslate">
mediaApp.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/', {templateUrl: 'views/media-list.html',   controller: 'MediaListCtrl'});
}]);
</pre>
<p>You can specify multiple paths for different URLs as well as a fallback. More on route configuration can be found <a href="http://docs.angularjs.org/api/ng.$routeProvider">here</a>.</p>
<h3>Quick Start</h3>
<p>You can use the <a href="https://github.com/angular/angular-seed">AngularJS seed project</a>, or if you&#8217;re familiar with <a href="http://yeoman.io">Yeoman</a>, there&#8217;s a whole option to generate an AngularJS-based project as well as additional commands that can be run to add new routes, views, controllers etc. It&#8217;s actually really cool and easy to use, check out <a href="http://briantford.com/blog/angular-yeoman.html">this article</a> for an awesome walkthrough of it. It will even generate your stubbed out tests for testing with Jasmine / Testacular. They can&#8217;t make it much easier for us than that <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ! I didn&#8217;t discover this until after I created my application so my project structure doesn&#8217;t follow the Yeoman structure, but instead mirrors the <a href="https://github.com/angular/angular-seed">AngularJS seed project</a> structure. There are also seed projects available for using <a href="https://github.com/btford/angular-express-seed">AngularJS on the front-end and Express+Node on the backend here</a>, as well as <a href="https://github.com/btford/angular-socket-io-seed">AngularJS on the front-end, and Socket.io+Express+Node here</a> if that fits your needs. </p>
<p>I&#8217;ve only scratched the surface of what this framework is about. Below is a list of resources that can be used to follow-up with more in-depth information for those interested. The AngularJS documentation is good and the community support as well from my experience. Next I plan to turn my Media Explorer web application into a mobile application using <a href="http://phonegap.com">PhoneGap</a> and will post it here so check back soon!</p>
<h3>Useful Resources</h3>
<ul>
<li><a href="http://net.tutsplus.com/tutorials/javascript-ajax/5-awesome-angularjs-features/">5 Awesome AngularJS Features</a></li>
<li><a href="http://twitter.com/@briantford">@briantford</a> on <a href="http://briantford.com/blog/huuuuuge-angular-apps.html">Building huuuuuuge Angular apps</a></li>
<li><a href="http://blog.angularjs.org/2012/07/introducing-angularjs-batarang.html">AngularJS Batarang &#8211; Chrome Extension for Debugging</a></li>
<li><a href="https://groups.google.com/forum/?fromgroups#!forum/angular">AngularJS Forum</a></li>
<li><a href="https://plus.google.com/+AngularJS/posts">AngularJS on Google+</a></li>
<li><a href="http://www.cheatography.com/proloser/cheat-sheets/angularjs/">AngularJS Cheat Sheet</a></li>
<li><a href="http://docs.angularjs.org">AngularJS Docs</a></li>
<li><a href="http://blog.angularjs.org/?view=flipcard">AngularJS Blog</a></li>
<li><a href="http://twitter.com/@briantfod">@briantford</a> on <a href="http://briantford.com/blog/angular-phonegap.html">Brian Ford on AngularJS with PhoneGap</a></li>
<li><a href="http://twitter.com/@simpulton">@simpulton</a> on <a href="http://onehungrymind.com/notes-on-angularjs-scope-life-cycle/">The AngularJS Scope LifeCycle</a></li>
<li><a href="http://blog.artlogic.com/2013/03/06/angularjs-for-jquery-developers/">AngularJS for jQuery Developers</a></li>
<li><a href="http://twitter.com/@simpulton">@simpulton</a> <a href="http://onehungrymind.com/category/angularjs/">blog &#8211; lots of useful articles on AngularJS</a>
<li>Dean Sofer &#8211; <a href="http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED">AngularJS Tips and Tricks</a></li>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2013%2F03%2F21%2Ffun-with-angularjs%2F&amp;title=Fun%20with%20AngularJS%21" id="wpa2a_4"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2013/03/21/fun-with-angularjs/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>ADC Web Standards Monthly &#8211; FREE Newsletter</title>
		<link>http://devgirl.org/2013/02/12/adc-web-standards-monthly-free-newsletter/</link>
		<comments>http://devgirl.org/2013/02/12/adc-web-standards-monthly-free-newsletter/#comments</comments>
		<pubDate>Tue, 12 Feb 2013 23:55:17 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML/JS]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ADC newsletter]]></category>
		<category><![CDATA[Adobe Developer newsletter]]></category>
		<category><![CDATA[free HTML5 newsletter]]></category>
		<category><![CDATA[free mobile development newsletter]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=5161</guid>
		<description><![CDATA[Brian Rinaldi at the Adobe Developer Connection (ADC) has recently put together a free monthly newsletter to help keep you up to date on all the latest and greatest content available on the ADC. The topics span a variety of subjects including HTML5, JavaScript, CSS, Mobile Development, PhoneGap, Responsive Design and more. The January newsletter [...]]]></description>
				<content:encoded><![CDATA[<p><img src="https://learn.adobe.com/wiki/download/attachments/13631811/logo48.png?version=1&#038;modificationDate=1203726267000" width="48" height="48" class="alignleft" /><a href="http://twitter.com/remotesynth/">Brian Rinaldi</a> at the <a href="http://www.adobe.com/devnet.html">Adobe Developer Connection (ADC)</a> has recently put together a free monthly newsletter to help keep you up to date on all the latest and greatest content available on the ADC. The topics span a variety of subjects including HTML5, JavaScript, CSS, Mobile Development, PhoneGap, Responsive Design and more. The January newsletter can be found <a href="http://us6.campaign-archive2.com/?u=231f8aff82a1f82e4d6ab23d8&#038;id=50a15c0984">here</a>. To start receiving this newsletter, simply <a href="http://remotesynthesis.us6.list-manage2.com/subscribe?u=231f8aff82a1f82e4d6ab23d8&#038;id=cc957a1e73">subscribe here</a> and you will start receiving it monthly to ensure you won&#8217;t miss the latest and greatest content available. There&#8217;s a great deal of new content written specifically for ADC coming, so be sure to <a href="http://remotesynthesis.us6.list-manage2.com/subscribe?u=231f8aff82a1f82e4d6ab23d8&#038;id=cc957a1e73">sign up</a>, takes literally two seconds! See <a href="http://remotesynthesis.com/">Brian&#8217;s blog</a> for more details and other great HTML5/CSS/JavaScript roundups as well. </p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2013%2F02%2F12%2Fadc-web-standards-monthly-free-newsletter%2F&amp;title=ADC%20Web%20Standards%20Monthly%20%E2%80%93%20FREE%20Newsletter" id="wpa2a_6"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2013/02/12/adc-web-standards-monthly-free-newsletter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Push Notifications Plugin Support added to PhoneGap Build</title>
		<link>http://devgirl.org/2013/01/24/push-notifications-plugin-support-added-to-phonegap-build/</link>
		<comments>http://devgirl.org/2013/01/24/push-notifications-plugin-support-added-to-phonegap-build/#comments</comments>
		<pubDate>Thu, 24 Jan 2013 19:44:16 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Cordova]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[Push Notifications]]></category>
		<category><![CDATA[android push notifications phonegap]]></category>
		<category><![CDATA[cordova push notifications]]></category>
		<category><![CDATA[ios push notifications phonegap]]></category>
		<category><![CDATA[phonegap build]]></category>
		<category><![CDATA[phonegap build push notifications]]></category>
		<category><![CDATA[push notifications]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=5135</guid>
		<description><![CDATA[I&#8217;m happy to post today there is now support for a generic push notifications plugin for PhoneGap Build. The new plugin is called PushPlugin and works for both iOS and Android push notifications. The iOS support is based on the Apple Push Notifications Service (APNS) and the Android support is based on Google Cloud Messaging [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://devgirl.org/2013/01/24/push-notifications-plugin-support-added-to-phonegap-build/pgb/" rel="attachment wp-att-5137"><img src="http://devgirl.org/wp-content/uploads/2013/01/pgb.jpg" alt="pgb" width="244" height="207" class="alignleft size-full wp-image-5137" /></a> I&#8217;m happy to post today there is now support for a generic push notifications plugin for <a href="http://build.phonegap.com">PhoneGap Build</a>. The new plugin is called <a href="https://github.com/phonegap-build/PushPlugin">PushPlugin</a> and works for both iOS and Android push notifications. The iOS support is based on the <a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html">Apple Push Notifications Service (APNS)</a> and the Android support is based on <a href="http://developer.android.com/google/gcm/index.html">Google Cloud Messaging (GCM)</a>. This has been a highly awaited need and I&#8217;m so glad I can finally share the good news. <a href="http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/apple-push-notification-service-2/" rel="attachment wp-att-4686"><img src="http://devgirl.org/wp-content/uploads/2012/10/apple-push-notification-service1.jpeg" alt="apple-push-notification-service" width="195" height="212" class="alignright size-full wp-image-4686" /></a></p>
<p>The details are all outlined well <a href="https://github.com/phonegap-build/PushPlugin">here</a> with some sample code but I also created a <a href="https://github.com/hollyschinsky/PhoneGapBuildPushProject2">quick sample project</a> you can use for a reference that will work for both iOS and Android. I put the whole project including the XCode project in <a href="https://github.com/hollyschinsky/PhoneGapBuildPushProject2/blob/master/www/js/index.js">github</a>, but you really only need the <strong>www</strong> folder for PhoneGap Build. There&#8217;s also a <a href="https://build.phonegap.com/docs/config-xml">config.xml</a> included you can use that includes the plugin reference there and is required for the native code to be added when built through PhoneGap Build. You will just need to change the application name, author and personal information in there to match your own <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  You will also need to change the GCM id to match your sender id in the <a href="https://github.com/hollyschinsky/PhoneGapBuildPushProject2/blob/master/www/js/index.js">index.js</a> file. Also, see my previous tutorials on push notifications for <a href="http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/">iOS</a> and <a href="http://devgirl.org/2012/10/25/tutorial-android-push-notifications-with-phonegap/">Android</a> to get some sample code in PHP or node.js to send a push notification quickly for testing so you can see it all in action. Those posts used the previous plugins available however, you should use the most currently supported <a href="https://github.com/phonegap-build/PushPlugin">PushPlugin</a> one now. Those posts also talk in-depth about signing up for GCM and how to use APNS as well. </p>
<p>I will also be holding two webinars on push notifications in February via <a href="http://techlive.adobe.com/">Adobe TechLive</a>, so come check those out for a walkthrough of how to get started with adding push notifications to your application for iOS and Android. I will talk more about the APIs and how to use them at that time as well. The PhoneGap Build team is busy working on additional support for more plugins. The currently supported ones can be found here: http://build.phonegap.com/docs/plugins.</p>
<p>The important parts of the code are outlined in the<a href="https://github.com/phonegap-build/PushPlugin"> PushPlugin documentation</a> but I&#8217;m also showing them from my sample here. It&#8217;s easier to see quickly how this new plugin could be used to register your device to receive notifications, and how you might handle the incoming message simply in the following:</p>
<pre class="brush: jscript; title: ; notranslate">
    receivedEvent: function(id) {
        var pushNotification = window.plugins.pushNotification;
        if (device.platform == 'android' || device.platform == 'Android') {
            pushNotification.register(successHandler, errorHandler,{&quot;senderID&quot;:&quot;834841663931&quot;,&quot;ecb&quot;:&quot;onNotificationGCM&quot;});
        }
        else {
            pushNotification.register(this.tokenHandler,this.errorHandler,   {&quot;badge&quot;:&quot;true&quot;,&quot;sound&quot;:&quot;true&quot;,&quot;alert&quot;:&quot;true&quot;,&quot;ecb&quot;:&quot;app.onNotificationAPN&quot;});
        }
...
    }

   // iOS
    onNotificationAPN: function(event) {
        var pushNotification = window.plugins.pushNotification;
        console.log(&quot;Received a notification! &quot; + event.alert);
        console.log(&quot;event sound &quot; + event.sound);
        console.log(&quot;event badge &quot; + event.badge);
        console.log(&quot;event &quot; + event);
        if (event.alert) {
            navigator.notification.alert(event.alert);
        }
        if (event.badge) {
            console.log(&quot;Set badge on  &quot; + pushNotification);
            pushNotification.setApplicationIconBadgeNumber(this.successHandler, event.badge);
        }
        if (event.sound) {
            var snd = new Media(event.sound);
            snd.play();
        }
    },
    // Android
    onNotificationGCM: function(e) {
        switch( e.event )
        {
            case 'registered':
                if ( e.regid.length &gt; 0 )
                {
                    // Your GCM push server needs to know the regID before it can push to this device
                    // here is where you might want to send it the regID for later use.
                    alert('registration id = '+e.regid);
                }
            break;

            case 'message':
              // this is the actual push notification. its format depends on the data model
              // of the intermediary push server which must also be reflected in GCMIntentService.java
              alert('message = '+e.message+' msgcnt = '+e.msgcnt);
            break;

            case 'error':
              alert('GCM error = '+e.msg);
            break;

            default:
              alert('An unknown GCM event has occurred');
              break;
        }
    }
</pre>
<p>Please see the <a href="https://github.com/hollyschinsky/PhoneGapBuildPushProject2/">sample</a> for the rest of the code. </p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2013%2F01%2F24%2Fpush-notifications-plugin-support-added-to-phonegap-build%2F&amp;title=Push%20Notifications%20Plugin%20Support%20added%20to%20PhoneGap%20Build" id="wpa2a_8"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2013/01/24/push-notifications-plugin-support-added-to-phonegap-build/feed/</wfw:commentRss>
		<slash:comments>63</slash:comments>
		</item>
		<item>
		<title>Introducing Adobe TechLive!</title>
		<link>http://devgirl.org/2012/12/20/introducing-adobe-techlive/</link>
		<comments>http://devgirl.org/2012/12/20/introducing-adobe-techlive/#comments</comments>
		<pubDate>Thu, 20 Dec 2012 10:38:26 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Adobe]]></category>
		<category><![CDATA[Cordova]]></category>
		<category><![CDATA[HTML/JS]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[Adobe TechLive]]></category>
		<category><![CDATA[Create the Web Tour]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[PhoneGap webinars]]></category>
		<category><![CDATA[TechLive]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=5109</guid>
		<description><![CDATA[Our team has been busy working on a new initiative called Adobe TechLive, a place where we&#8217;ll be hosting interactive online webinars on various topics. Some upcoming topics include Adobe&#8217;s Create the Web tour introducing Adobe&#8217;s latest new tools and web technologies, a PhoneGap Open Session where you can come to get your questions answered [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://techlive.adobe.com/"><img alt="" src="http://techlive.adobe.com/wp-content/uploads/2012/12/logo-HD-100x100.png" class="alignleft" width="100" height="100" /></a>Our team has been busy working on a new initiative called <a href="http://techlive.adobe.com/">Adobe TechLive</a>, a place where we&#8217;ll be hosting interactive online webinars on various topics. Some upcoming topics include Adobe&#8217;s <a href="http://techlive.adobe.com/ai1ec_event/create-the-web/?instance_id=632">Create the Web tour </a> introducing Adobe&#8217;s latest new tools and web technologies</a>, a <a href="http://techlive.adobe.com/ai1ec_event/open-phonegap-session/">PhoneGap Open Session</a> where you can come to get your questions answered about PhoneGap, PhoneGap Build and mobile development, a session on <a href="http://techlive.adobe.com/ai1ec_event/html5-storage/">HTML5 Storage</a> and much more to be added soon. </p>
<p>Check out the <a href="http://techlive.adobe.com/">site</a> and to join a session live, simply click on the event and you will see a <strong>Join the Live Event </strong>blue button at the top that will take you into it. If you miss a session, you can still watch the recorded version after the fact in the <a href="http://techlive.adobe.com/archives">archives</a>. Also, feel free to provide feedback for sessions or topics you might want to see covered in the future <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2012%2F12%2F20%2Fintroducing-adobe-techlive%2F&amp;title=Introducing%20Adobe%20TechLive%21" id="wpa2a_10"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2012/12/20/introducing-adobe-techlive/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Geo-based Push Notifications with PhoneGap and Pushwoosh</title>
		<link>http://devgirl.org/2012/12/11/geo-based-push-notifications-with-phonegap-and-pushwoosh/</link>
		<comments>http://devgirl.org/2012/12/11/geo-based-push-notifications-with-phonegap-and-pushwoosh/#comments</comments>
		<pubDate>Tue, 11 Dec 2012 15:13:21 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Cordova]]></category>
		<category><![CDATA[HTML/JS]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[android geofencing]]></category>
		<category><![CDATA[geofencing]]></category>
		<category><![CDATA[ios geofencing]]></category>
		<category><![CDATA[phonegap geofencing]]></category>
		<category><![CDATA[push notifications]]></category>
		<category><![CDATA[push notifications location]]></category>
		<category><![CDATA[pushwoosh]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=5022</guid>
		<description><![CDATA[Recently I blogged about sending push notifications via the Pushwoosh service and specifically with PhoneGap applications. While working with the service I noticed it had something built in for setting up geozones for your push notifications (aka: geofencing). If you&#8217;re not familiar with this term, it&#8217;s basically the ability to send push notifications to a [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://devgirl.org/wp-content/uploads/2012/12/geofencing2.jpg"><img src="http://devgirl.org/wp-content/uploads/2012/12/geofencing2.jpg" alt="" title="geofencing2" width="270" height="208" class="alignleft size-full wp-image-5082" /></a>Recently I <a href="http://devgirl.org/2012/12/04/easy-phonegap-push-notifications-with-pushwoosh/">blogged about sending push notifications</a> via the <a href="http://www.pushwoosh.com/">Pushwoosh</a> service and specifically with PhoneGap applications. While working with the service I noticed it had something built in for setting up geozones for your push notifications (aka: geofencing). If you&#8217;re not familiar with this term, it&#8217;s basically the ability to send push notifications to a device when it&#8217;s in a certain location or zone. There&#8217;s a really great article about it <a href="http://nikosdrak.wordpress.com/2012/02/23/geofencing-background-overview-the-market/">here</a>. This is something I&#8217;ve seen many real application uses for myself in my connections with people so I was particularly interested in trying out their service with it and sharing it. </p>
<div class='et-box et-warning'>
					<div class='et-box-content'>If you haven&#8217;t looked at the <a href="http://devgirl.org/2012/12/04/easy-phonegap-push-notifications-with-pushwoosh/">previous post</a> regarding the Pushwoosh service and push notifications, I suggest you do that first before continuing&#8230;</div></div>
<h3>Overview</h3>
<p>The way the Pushwoosh service implements geo-based notifications is by comparing the devices&#8217; current location to the geographic zones that were defined for that application either through their web interface or their APIs to see if there&#8217;s a match. An example of the interface to define them on their website is shown below:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/12/pushgeo1.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/pushgeo1.png" alt="" title="pushgeo1" width="650" height="418" class="alignleft size-full wp-image-5024" /></a></p>
<p>Notice the <strong>Find location</strong> link that brings up a map to help you find latitude/longitude more quickly and set it in your form as shown in the screenshot:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/12/pushgeo2.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/pushgeo2.png" alt="" title="pushgeo2" width="450" height="370" class="aligncenter size-full wp-image-5028" /></a></p>
<p>When a match is found, the notification text (and any additional settings including an HTML page or URL to open when the notification is clicked for advanced notifications) are then displayed.</p>
<h3>Use with PhoneGap</h3>
<p>Currently <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects">their sample PhoneGap applications</a> show this implemented with a combination of the <a href="http://docs.phonegap.com/en/2.2.0/cordova_geolocation_geolocation.md.html#Geolocation">PhoneGap Geolocation API</a> and the <a href="http://www.google.com/url?sa=t&#038;rct=j&#038;q=pushwoosh%20api&#038;source=web&#038;cd=1&#038;cad=rja&#038;ved=0CDAQFjAA&#038;url=http%3A%2F%2Fwww.pushwoosh.com%2Fprogramming-push-notification%2Fpushwoosh-push-notification-remote-api%2F&#038;ei=PsTAUKLvG-GgiQKUwIDQBQ&#038;usg=AFQjCNGW26cqR6WSVZ1KSlxHZiLm1BLiXg&#038;sig2=JOoHY1He4woW-Q04QBSmRQ">Pushwoosh APIs</a>. So the PhoneGap Geolocation API is used to track the users location via the following functions, which may vary depending on exactly how you want your application to track, but you get the idea:</p>
<pre class="brush: jscript; title: ; notranslate">
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
navigator.geolocation.watchPosition(geolocationSuccess, geolocationError, { maximumAge: 3000, enableHighAccuracy: true });
</pre>
<p>and when the device location changes, the following Pushwoosh PushNotification APIs are used to send the location (found in the <a href="https://github.com/shaders/push-notifications-sdk/blob/master/SDK%20Sample%20Projects/iPhone-Phonegap/www/PushNotification.js">PushNotification.js file</a> under each of the <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects/Android-Phonegap">Android-PhoneGap</a> and <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects/iPhone-Phonegap">iPhone-PhoneGap</a> projects):</p>
<pre class="brush: jscript; title: ; notranslate">
        //Android Only----
	PushNotification.prototype.unregisterDevice = function(success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;unregisterDevice&quot;, []);
	};
	
	PushNotification.prototype.startGeoPushes = function(success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;startGeoPushes&quot;, []);
	};

	PushNotification.prototype.stopGeoPushes = function(success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;stopGeoPushes&quot;, []);
	};

	//Android End----
	
	// Call this to send geo location for the device
	PushNotification.prototype.sendLocation = function(config, success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;sendLocation&quot;, config ? [config] : []);
	};

	PushNotification.prototype.onDeviceReady = function() {
		cordova.exec(null, null, &quot;PushNotification&quot;, &quot;onDeviceReady&quot;, []);
	};

	// Call this to get a detailed status of remoteNotifications
	PushNotification.prototype.getRemoteNotificationStatus = function(callback) {
		cordova.exec(callback, callback, &quot;PushNotification&quot;, &quot;getRemoteNotificationStatus&quot;, []);
	};

	// Call this to set the application icon badge
	PushNotification.prototype.setApplicationIconBadgeNumber = function(badge, callback) {
		cordova.exec(callback, callback, &quot;PushNotification&quot;, &quot;setApplicationIconBadgeNumber&quot;, [{badge: badge}]);
	};

	// Call this to clear all notifications from the notification center
	PushNotification.prototype.cancelAllLocalNotifications = function(callback) {
		cordova.exec(callback, callback, &quot;PushNotification&quot;, &quot;cancelAllLocalNotifications&quot;, []);
	};
</pre>
<p>An example of how this might look in your applications&#8217; JavaScript is below:</p>
<pre class="brush: jscript; title: ; notranslate">
deviceready: function() {
    navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
    navigator.geolocation.watchPosition(geolocationSuccess, geolocationError, { maximumAge: 3000, enableHighAccuracy: true });

    function geolocationSuccess(position) {
        pushNotification.sendLocation({lat:position.coords.latitude, lon:position.coords.longitude},
        function(status) {
           console.warn('sendLocation success');
        },
        function(status) {
           console.warn('sendLocation failed');
    });
    function geolocationError(error) {
	alert('code: '    + error.code    + '\n' +
	'message: ' + error.message + '\n');
    }
};
</pre>
<p>Download the <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects">complete sample for Android and iOS with PhoneGap here</a> for more details.</p>
<p>Additionally there are obviously some differences in the native code between iOS and Android and how things are handled, but I won&#8217;t go into detail about that here. One thing you should be aware of though is that on Android you need to call the following to start and stop receiving geo-based push notifications:</p>
<pre class="brush: jscript; title: ; notranslate">
pushNotification.startGeoPushes();
pushNotification.stopGeoPushes();
</pre>
<p>Refer to the <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects/Android-Phonegap">sample Android-PhoneGap project</a> for more details&#8230;</p>
<h3>iOS Handling</h3>
<p>As some may be thinking, on iOS the location updates will stop as soon as the application goes to the background. However, there is a flag you can set on your application to allow it to continue to receive location updates so you will still receive your notifications. The flag is set in the application .plist file to set the background mode (<strong>UIBackgroundModes</strong> is the official name of the key). Note that this .plist is different from the <strong>Cordova.plist</strong>, and is typically named as <strong><em>YourAppName-</em>Info.plist</strong>. </p>
<div class='et-box et-warning'>
					<div class='et-box-content'>Keeping the application in the background and performing continuous location pinging will use up the battery more quickly. On <a href="http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html">iOS there is a native low-power significant change location API available</a> that could be used instead (as opposed to the standard location API that the PhoneGap geolocation APIs use). I found a <a href="https://github.com/radshag/PhoneGap-Geofencing">PhoneGap Geofencing plugin</a> available that appears to do this but I haven&#8217;t tried it yet myself. Feel free to give it a try and post back <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</div></div>
<h3>Additional Notes and Links</h3>
<div class='et-box et-info'>
					<div class='et-box-content'>Note that the geozones are only available on memberships above the free level. View the  plans <a href="http://www.pushwoosh.com/accounts-comparison/">here</a>.</div></div>
<ul>
<li>Check out the <a href="http://www.pushwoosh.com/programming-push-notification/">Pushwoosh documentation</a> for more information.</li>
<li><a href="http://www.netmagazine.com/tutorials/get-started-geofencing-ios">Intro to geofencing on iOS article</a></li>
<li><a href="http://devgirl.org/2012/12/04/easy-phonegap-push-notifications-with-pushwoosh/">Easy PhoneGap Push Notifications with Pushwoosh</a>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2012%2F12%2F11%2Fgeo-based-push-notifications-with-phonegap-and-pushwoosh%2F&amp;title=Geo-based%20Push%20Notifications%20with%20PhoneGap%20and%20Pushwoosh" id="wpa2a_12"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2012/12/11/geo-based-push-notifications-with-phonegap-and-pushwoosh/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Easy PhoneGap Push Notifications with Pushwoosh</title>
		<link>http://devgirl.org/2012/12/04/easy-phonegap-push-notifications-with-pushwoosh/</link>
		<comments>http://devgirl.org/2012/12/04/easy-phonegap-push-notifications-with-pushwoosh/#comments</comments>
		<pubDate>Tue, 04 Dec 2012 20:57:42 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Cordova]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[geofence]]></category>
		<category><![CDATA[geofencing]]></category>
		<category><![CDATA[phonegap geofencing]]></category>
		<category><![CDATA[phonegap push notifications]]></category>
		<category><![CDATA[push notification service]]></category>
		<category><![CDATA[push notifications]]></category>
		<category><![CDATA[push notifications windows phone]]></category>
		<category><![CDATA[pushwoosh]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=4838</guid>
		<description><![CDATA[I recently posted regarding the use of Push Notifications on both iOS and Android with PhoneGap. Both of those addressed sending push notifications from a general 3rd party server where you write the server side push code. However, there are many services out there you can leverage for sending push notifications as well and this [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://devgirl.org/wp-content/uploads/2012/12/pw-logo3.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/pw-logo3.png" alt="" title="pw-logo" width="105" height="99" class="alignleft size-full wp-image-5041" /></a>I recently posted regarding the use of Push Notifications on both <a href="http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/">iOS</a> and <a href="http://devgirl.org/2012/10/25/tutorial-android-push-notifications-with-phonegap/">Android</a> with <a href="http://www.phonegap.com/">PhoneGap</a>. Both of those addressed sending push notifications from a general 3rd party server where you write the server side push code. However, there are many services out there you can leverage for sending push notifications as well and this post will address <a href="http://www.pushwoosh.com">Pushwoosh</a> in particular. </p>
<p>What&#8217;s nice about Pushwoosh is they have a free offering with basic push features to get you started and their service applies to multiple platforms in general as well as offering plugins and samples for PhoneGap applications targeting <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects/iPhone-Phonegap">iOS</a>, <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects/Android-Phonegap">Android,</a> and <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects/WP7-Phonegap">Windows Phone 7</a>. I noticed there also appears to be a <a href="https://github.com/shaders/pushwoosh-phonegap-build-plugin">plugin available and supported with <a href="https://build.phonegap.com/">PhoneGap Build</a>. With all the PhoneGap support it seemed like a great service to blog about in addition to my recent push notification posts.</p>
<h3>Overview</h3>
<p>To use Pushwoosh, your PhoneGap application uses a <a href="https://github.com/shaders/push-notifications-sdk/tree/master/SDK%20Sample%20Projects"><strong><em>PushNotification</em></strong> plugin</a> to communicate with the <a href="http://www.pushwoosh.com/programming-push-notification/pushwoosh-push-notification-remote-api/">Pushwoosh APIs</a>. You configure this plugin just like any other. For iOS you add it to the Cordova.plist and put the classes in the plugins folder. Below is an example of how the plugin looks in the Cordova.plist.<br />
<a href="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-04-at-1.01.07-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-04-at-1.01.07-PM.png" alt="" title="Screen Shot 2012-12-04 at 1.01.07 PM" width="496" height="104" class="alignlcenter size-full wp-image-4980" /></a></p>
<p>For Android you include the jars/java files and add the plugin to the list of plugins for your app (usually in config.xml or cordova.xml), for instance:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;plugins&gt;
...
    &lt;plugin name=&quot;Camera&quot; value=&quot;org.apache.cordova.CameraLauncher&quot;/&gt;
    &lt;plugin name=&quot;Contacts&quot; value=&quot;org.apache.cordova.ContactManager&quot;/&gt;
    &lt;plugin name=&quot;PushNotification&quot; value=&quot;com.pushwoosh.test.plugin.pushnotifications.PushNotifications&quot; onload=&quot;true&quot;/&gt;
...
&lt;/plugins&gt;
</pre>
<p>For both platforms you&#8217;ll see a <strong>PushNotification.js</strong> file in the samples that has a set of calls for registering/unregistering for push notifications, as well as some other nice functions (sending current location, getting status etc), an excerpt is shown below: </p>
<pre class="brush: jscript; title: ; notranslate">
...
	// Call this to register for push notifications and retreive a deviceToken
	PushNotification.prototype.registerDevice = function(config, success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;registerDevice&quot;, config ? [config] : []);
	};

	// Call this to set tags for the device
	PushNotification.prototype.setTags = function(config, success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;setTags&quot;, config ? [config] : []);
	};

	//Android Only----
	PushNotification.prototype.unregisterDevice = function(success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;unregisterDevice&quot;, []);
	};
	
	PushNotification.prototype.startGeoPushes = function(success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;startGeoPushes&quot;, []);
	};

	PushNotification.prototype.stopGeoPushes = function(success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;stopGeoPushes&quot;, []);
	};

	//Android End----
	
	//iOS only----
	// Call this to send geo location for the device
	PushNotification.prototype.sendLocation = function(config, success, fail) {
		cordova.exec(success, fail, &quot;PushNotification&quot;, &quot;sendLocation&quot;, config ? [config] : []);
	};
..
</pre>
<div class='et-box et-download'>
					<div class='et-box-content'>Actual example usage of the PushNotification.js calls from JavaScript can be found under the Android Setup section further on in this post&#8230;</div></div>
<h3>Getting Started</h3>
<div class='et-box et-info'>
					<div class='et-box-content'>It will save you time to keep <a href="http://www.pushwoosh.com/programming-push-notification/">this link </a>open in a browser for the Pushwoosh documentation reference.</div></div>
<ul>
<li>Go to <a href="http://www.pushwoosh.com/">the Pushwoosh website</a>, click on <strong>Start Now</strong> and sign up for a free account/</li>
<li>Once logged in, you will be taken to an applications page.</li>
<li>Create a new application and name it something meaningful to you. The name doesn&#8217;t have to match anything in particular, but you will use the associated app id (more to come on that).</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/12/pushwooshSS-newapp.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/pushwooshSS-newapp.png" alt="" title="pushwooshSS-newapp" width="650" height="310" class="aligncenter size-full wp-image-4932" /></a></p>
<li>Once created, configure the different platforms your application will run on. In my case I just configured iOS and Android for use with a PhoneGap application. </li>
<li>Android Configuration requires a <a href="http://developer.android.com/google/gcm/index.html">Google Cloud Messaging</a> API Key (see below for more setup details):<br />
<a href="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-03-at-2.37.39-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-03-at-2.37.39-PM.png" alt="" title="Screen Shot 2012-12-03 at 2.37.39 PM" width="539" height="385" class="aligncenter size-full wp-image-4934" /></a></li>
<li>iOS Configuration requires your Apple certificate (.cer file) and key (.p12) if you&#8217;re using the manual and free service:<br />
<a href="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-03-at-2.39.21-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-03-at-2.39.21-PM.png" alt="" title="Screen Shot 2012-12-03 at 2.39.21 PM" width="537" height="500" class="aligncenter size-full wp-image-4935" /></a></p>
<p>There&#8217;s a guide to specifically getting the certificate and key set up through Apple <a href="http://www.pushwoosh.com/programming-push-notification/iphone-configuration-guide/">here</a>, or you can also visit <a href="http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/">my Push Notifications for iOS post</a>. </p>
<div class='et-box et-warning'>
					<div class='et-box-content'>Be sure to use the exact app ID and package name chosen in the Apple Developer Portal in your iOS application in XCode as well. If you&#8217;ve ever done push notifications with iOS this should be a familiar process to you.</div></div>
<p><div class='et-box et-info'>
					<div class='et-box-content'>If you have a premium account much of this manual configuration work can be done for you by just entering your Apple credentials in the Auto tab above.</div></div>
</li>
</ul>
<h3>Android Application Setup</h3>
<h4>Requirements</h4>
<ul>
<li><a href="http://developer.android.com/google/gcm/index.html">Google Cloud Messaging (GCM) Project Number</a><br />
It can be found in the URL after the #project, for example my GCM console URL is: https://code.google.com/apis/console/#project:824842663931, so my GCM project # is 824842663931.
</li>
<li>Pushwoosh App ID<br />
This is found when you click on any of the applications defined within Pushwoosh, such as circled in the screenshot below:
</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/pushwooshSS-copy1.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/pushwooshSS-copy1.png" alt="" title="pushwooshSS copy" width="650" height="419" class="aligncenter size-full wp-image-4928"/></a></p>
</ul>
<h4>Steps</h4>
<ol>
<li>Download the Pushwoosh Android for PhoneGap sample either from the <a href="https://cp.pushwoosh.com/applications">Pushwoosh applications page</a> by hovering over the platform such as shown in the screenshot below, or go to <a href="https://github.com/shaders/push-notifications-sdk/blob/master/SDK%20Sample%20Projects/">this link</a> to always grab the latest (be sure to pick the Android-PhoneGap link).</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/12/PWSample.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/PWSample.png" alt="" title="PWSample" width="680" height="524" class="aligncenter size-full wp-image-4942" /></a></li>
<li>Now follow <a href="http://www.pushwoosh.com/programming-push-notification/android-gcm-push-notifications-guide/">these instructions</a> to make <strong><em>your</em></strong> application work with Pushwoosh. Step 6 is where you need to use your own GCM project number and Pushwoosh app id as noted in the requirements. Here&#8217;s an example of some code to register the device and listen for push notifications:
<pre class="brush: jscript; title: ; notranslate">
initPushwoosh: function() {
    	var pushNotification = window.plugins.pushNotification;
	pushNotification.registerDevice({ projectid: &quot;824842663931&quot;, appid : &quot;A49E7-43076&quot; },
	        function(status) {
	            var pushToken = status;
	            console.warn('push token: ' + pushToken);
	        },
	        function(status) {
	            console.warn(JSON.stringify(['failed to register ', status]));
	        }
	);
    	document.addEventListener('push-notification', function(event) {	    	
	        var title = event.notification.title;
	        var userData = event.notification.userdata;
	        if (typeof(userData) != &quot;undefined&quot;) {
	           console.warn('user data: ' + JSON.stringify(userData));
	        }	 
	        navigator.notification.alert(title);
	});
    },
</pre>
</li>
</ol>
<div class='et-box et-info'>
					<div class='et-box-content'>By default you will not see notifications while the application is running or in the foreground. If you would like to still receive them while the application is open on Android, uncomment the following line in the <strong>PushNotification.java</strong> code:</p>
<pre class="brush: java; title: ; notranslate">
//uncomment this code if you would like to receive the notifications in the app bypassing notification center if the app is in the foreground
cordova.getActivity().registerReceiver(mReceiver, intentFilter);
</pre></div></div>
<h3>iOS Application Setup</h3>
<ol>
<li>
Retrieve your Pushwoosh App ID. As above, this is found when you click on any of the applications defined within Pushwoosh, such as circled in the screenshot below:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/pushwooshSS-copy1.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/pushwooshSS-copy1.png" alt="" title="pushwooshSS copy" width="650" height="419" class="aligncenter size-full wp-image-4928"/></a>
</li>
<li>
Next simply follow <a href="http://www.pushwoosh.com/programming-push-notification/push-notification-sdk-integration-for-phonegap/">the in-depth instructions here</a>.
</li>
</ol>
<h3>Other Cool Stuff</h3>
<ul>
<li>
<strong>Stats</strong><br />
The Pushwoosh web client also has a <strong>Stats</strong> page to help you determine how many messages you&#8217;ve pushed etc. You can also determine if the messages were successful or potential errors by combining data here along with the <strong><em>Pushes</em></strong> page. Here are a couple of screenshots from <strong><em>Stats</em></strong> and <strong>Pushes</strong> pages respectively:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/12/PWStats.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/PWStats.png" alt="" title="PWStats" width="660" height="532" class="aligncenter size-full wp-image-4948" /></a><br />
<a href="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-04-at-1.57.42-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/Screen-Shot-2012-12-04-at-1.57.42-PM.png" alt="" title="Screen Shot 2012-12-04 at 1.57.42 PM" width="550" height="306" class="alignleft size-full wp-image-4981" /></a>
</li>
<li>
<strong>Advanced Notifications</strong><br />
You can configure more advanced notifications that can have the notification open a URL or custom page when clicked containing HTML content and images etc. You can also set a special sound for iOS and Android, a badge (iOS), and options in the advanced notifications options.<br />
<a href="http://devgirl.org/wp-content/uploads/2012/12/pushwooshAdv.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/pushwooshAdv.png" alt="" title="pushwooshAdv" width="600" height="414" class="aligncenter size-full wp-image-4961" /></a>
</li>
<li>
<div align="center">Here&#8217;s a screenshot of how you can use their website to create a new page to be shown upon notification click:</div>
<p><a href="http://devgirl.org/wp-content/uploads/2012/12/pushwooshPage.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/pushwooshPage.png" alt="" title="pushwooshPage" width="240" height="438" class="aligncenter size-full wp-image-4958" /></a></p>
<div align="center">And here it is when opened on iOS from clicking the notification:</div>
<p><a href="http://devgirl.org/wp-content/uploads/2012/12/photo-9-copy.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/photo-9-copy.png" alt="" title="photo (9) copy" width="300" height="450" class="aligncenter size-full wp-image-4956" /></a></p>
</li>
<li>
<strong>Geozones</strong><br />
You can set up locations as zones to automatically push messages to the device when it has entered that zone through their Geozones feature. This is very useful for geofencing type apps. More to come in a further blog post on that!
</li>
<li>
<strong>Tags</strong><br />
Use their API&#8217;s for setting tags to identify different types of users or preferences etc. <a href="http://www.pushwoosh.com/pushwoosh-2-5-episode-2-all-kinds-of-tags-2/">More information about Pushwoosh and using tags can be found here</a>.<br />
<div class='et-box et-info'>
					<div class='et-box-content'>The PhoneGap plugins for Pushwoosh include support for this as well <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</div></div></p>
<li>
<strong>Great Support</strong><br />
I was very impressed with the support I received while trying out this service. They were quick to respond with meaningful information and went out of their way to add some additional code to aid in some specific testing I was doing to try out their geozones offering which I will be posting about specifically next.
</li>
<li>
<strong>New Features Coming&#8230;</strong><br />
In my exchanges I was also informed of some cool new features in the works and big enhancements to their Stats and website overall so it definitely seems like a great option to check out! Keep up with the latest happenings on their blog <a href="http://www.pushwoosh.com/blog/">here</a>.
</li>
</ul>
<h3>Pushwoosh Plans</h3>
<p>Here&#8217;s a quick summary page of the options available through Pushwoosh currently:<br />
<a href="http://devgirl.org/wp-content/uploads/2012/12/pushwooshSSplans.png"><img src="http://devgirl.org/wp-content/uploads/2012/12/pushwooshSSplans.png" alt="" title="pushwooshSSplans" width="680" height="513" class="aligncenter size-full wp-image-4936" /></a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2012%2F12%2F04%2Feasy-phonegap-push-notifications-with-pushwoosh%2F&amp;title=Easy%20PhoneGap%20Push%20Notifications%20with%20Pushwoosh" id="wpa2a_14"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2012/12/04/easy-phonegap-push-notifications-with-pushwoosh/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Tutorial: Embed PhoneGap as a Subview in your Native iOS Application</title>
		<link>http://devgirl.org/2012/11/15/embed-cordovaphonegap-in-your-native-ios-app/</link>
		<comments>http://devgirl.org/2012/11/15/embed-cordovaphonegap-in-your-native-ios-app/#comments</comments>
		<pubDate>Thu, 15 Nov 2012 15:35:17 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Cordova]]></category>
		<category><![CDATA[HTML/JS]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[cordova in native application]]></category>
		<category><![CDATA[cordova native]]></category>
		<category><![CDATA[cordova webview]]></category>
		<category><![CDATA[embed Cordova WebView]]></category>
		<category><![CDATA[embed phonegap]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=4840</guid>
		<description><![CDATA[Something cool that many mobile developers (and particularly native developers) might not be aware of at this point, is the option to use PhoneGap (aka Cordova) as a component within your mobile application, as a web &#8220;subview&#8221; of a whole native application where you want to render HTML/JS content and/or interact with the PhoneGap APIs. [...]]]></description>
				<content:encoded><![CDATA[<p>Something cool that many mobile developers (and particularly native developers) might not be aware of at this point, is the option to use <a href="http://www.phonegap.com/">PhoneGap</a> (aka Cordova) as a component within your mobile application, as a web &#8220;subview&#8221; of a whole native application where you want to render HTML/JS content and/or interact with the <a href="http://docs.phonegap.com/en/2.2.0/index.html">PhoneGap APIs</a>. In this webview component (sometimes also referred to as <strong><em>Cleaver</em></strong>), you can do anything a traditional PhoneGap application would do, such as access native features like the camera or contacts etc too. This post will expand <a href="http://docs.phonegap.com/en/2.2.0/guide_cordova-webview_ios.md.html#Embedding%20Cordova%20WebView%20on%20iOS">the steps here </a>and show you <a href="https://github.com/hollyschinsky/NativeAppEmbedWebView">a sample application</a> you could download and try yourself. Note that I am not an Objective-C native programmer, but this is just a simple example to show off the capabilities and create awareness. Feel free to post your application or source if you have used this and would like to share with others <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . </p>
<h3>Steps to Embed Cordova WebView</h3>
<p>Below are detailed steps on including PhoneGap/Cordova as a web subview in your native application. At the end of this section I show screenshots from a <a href="https://github.com/hollyschinsky/NativeAppEmbedWebView">sample application</a> I made available on my github account for you to try this out yourself or refer to things as needed.</p>
<ol>
<li>Create your base native iOS application in XCode (version 4.5 recommended) unless you just plan to add to an existing native application.</li>
<p>In my case I chose to create a new <em>Single View Application</em> in XCode such as the following:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/xcode7.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/xcode7.png" alt="" title="xcode7" width="600" height="402" class="aligncenter size-full wp-image-4888" /></a></p>
<li><a href="https://github.com/apache/incubator-cordova-ios">Download and extract the Cordova source</a> to a permanent folder location on your hard drive (for example: ~/Documents/Cordova). </li>
<div class='et-box et-info'>
					<div class='et-box-content'>You&#8217;ll need this for copying Cordova resources into your native application.</div></div>
<li>Close any other Cordova projects and exit XCode (XCode can be quirky, a restart often clears up potential or possible errors).</li>
<li>Navigate to the directory where you put the downloaded Cordova source above and copy the <strong>Cordova.plist</strong> file into your native application folder on the file system (at same level as the AppDelegate files etc, see picture below). <strong>Note: </strong>you could also use a <strong>Cordova.plist</strong> from a newly created Cordova application.
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-1.40.36-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-1.40.36-PM.png" alt="" title="Screen Shot 2012-11-08 at 1.40.36 PM" width="308" height="292" class="aligncenter size-full wp-image-4842" /></a></p>
<p><div class='et-box et-info'>
					<div class='et-box-content'>This file contains specific Cordova property settings and plugins required for your application to use Cordova.</div></div>
</li>
<li>Drag and drop the <strong>Cordova.plist</strong> file into the Project Navigator of Xcode</li>
<li>Choose the radio-button <strong>&#8220;Create groups for any added folders&#8221;</strong>, select the <strong>Finish</strong> button</li>
<li>Go to the downloaded source from the previous step above and locate the <strong>CordovaLib.xcodeproj </strong>in the <strong><em>CordovaLib</em></strong> sub-folder. Drag and drop the <strong>CordovaLib.xcodeproj</strong> file into the Project Navigator of XCode (at the same level as the <em>.plist</em> file copied in above &#8211; again choosing &#8216;<strong>Create groups for any added folders</strong>&#8216;)
</li>
<li>Select <strong>CordovaLib.xcodeproj</strong> in the Project Navigator</li>
<li>Open the <strong>File Inspector</strong> with Option-Command-1 or by going to <strong>View | Utilities | Show File Inspector</strong></li>
<li>Ensure that it says <strong>&#8220;Relative to Group&#8221;</strong> in the File Inspector for the<strong> Location </strong>drop-down menu similar to below:</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-2.57.58-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-2.57.58-PM.png" alt="" title="Screen Shot 2012-11-08 at 2.57.58 PM" width="344" height="169" class="aligncenter size-full wp-image-4844" /></a></p>
<li>Select the project icon in the Project Navigator, select your application under <strong>&#8220;TARGETS&#8221;</strong> (should have an A next to it), then select the <strong>&#8220;Build Settings&#8221;</strong> tab as shown below:</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/xcode2.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/xcode2.png" alt="" title="xcode2" width="590" height="335" class="alignleft size-full wp-image-4863" /></a></p>
<li>Locate the setting for <strong>&#8220;Other Linker Flags&#8221;</strong> (under the <strong>Linking</strong> section) and double-click the value text field to bring up the box to enter the flags <code>-all_load</code> and <code>-Obj-C</code> as shown here:</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-3.13.46-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-3.13.46-PM.png" alt="" title="Screen Shot 2012-11-08 at 3.13.46 PM" width="610" height="329" class="alignleft size-full wp-image-4850" /></a></p>
<li>
Select the project icon in the Project Navigator, select your target, then select the <strong>&#8220;Build Phases&#8221;</strong> tab.</li>
<li>Expand <strong>&#8220;Link Binaries with Libraries&#8221;</strong>. Select the &#8220;+&#8221; button, and add these frameworks (and optionally in the Project Navigator, move them under the <strong>Frameworks</strong> group):
<p><strong>AddressBook.framework<br />
AddressBookUI.framework<br />
AudioToolbox.framework<br />
AVFoundation.framework<br />
CoreLocation.framework<br />
MediaPlayer.framework<br />
QuartzCore.framework<br />
SystemConfiguration.framework<br />
MobileCoreServices.framework<br />
CoreMedia.framework</p>
<p></strong></li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/xcode11.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/xcode11.png" alt="" title="xcode1" width="610" height="306" class="alignleft size-full wp-image-4862" /></a></p>
<li>Now expand &#8220;<strong>Target Dependencies</strong>&#8221;<br />
Select the &#8220;+&#8221; button, and add the <strong>CordovaLib</strong> build product</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-4.45.16-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-08-at-4.45.16-PM.png" alt="" title="Screen Shot 2012-11-08 at 4.45.16 PM" width="660" height="228" class="aligncenter size-full wp-image-4855" /></a>
</li>
<li>
Expand &#8220;<strong>Link Binaries with Libraries</strong>&#8221; again and add <strong>libCordova.a</strong>
</li>
<li>
Go to &#8220;<strong>Xcode Preferences -> Locations -> Derived Data -> Advanced…</strong>&#8221; and ensure it is set to &#8220;<strong>Unique</strong>&#8221;
</li>
<li>
Go back to Build Settings and locate the <strong>Header Search Paths</strong> and ensure the following properties are set (including the quotes):<br />
<strong>&#8220;$(TARGET_BUILD_DIR)/usr/local/lib/include&#8221;<br />
&#8220;$(OBJROOT)/UninstalledProducts/include&#8221;<br />
&#8220;$(BUILT_PRODUCTS_DIR)&#8221;<br />
</strong></li>
<p>The result should look like the following:<br />
<a href="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-14-at-4.25.35-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-14-at-4.25.35-PM.png" alt="" title="Screen Shot 2012-11-14 at 4.25.35 PM" width="677" height="304" class="aligncenter size-full wp-image-4899" /></a>
</ol>
<h3>Code Additions</h3>
<p>To actually use the subview, you need to add the following Objective-C code where you want to include it.<br />
<strong>Import the following header</strong></p>
<pre class="brush: cpp; title: ; notranslate">
#import &lt;Cordova/CDVViewController.h&gt;
</pre>
<p><strong>Instantiate a new <code>CDVViewController</code></strong></p>
<pre class="brush: cpp; title: ; notranslate">
CDVViewController* viewController = [CDVViewController new];
</pre>
<p><strong>Set up the view frame</strong></p>
<pre class="brush: cpp; title: ; notranslate">
viewController.view.frame = CGRectMake(0, 0, 320, 480);
</pre>
<p><strong>Lastly, add to your view as a subview</strong></p>
<pre class="brush: cpp; title: ; notranslate">
[myView addSubview:viewController.view];
</pre>
<p>You could optionally set the <em>www</em> folder, start page or option to show the splash screen to something other than the default (default folder is www, start page is index.html and splash screen is no) on that <strong>CDVViewController</strong> as well with the following lines:</p>
<pre class="brush: cpp; title: ; notranslate">
viewController.wwwFolderName = @&quot;myfolder&quot;;
viewController.startPage = @&quot;mystartpage.html&quot;;
viewController.useSplashScreen = YES;
</pre>
<p>Here&#8217;s an example of actually implementing those lines above in my <strong>ViewController.m</strong> class that is created with a new native XCode <em>Single View</em> project like discussed above (the added code is in the <code>viewDidLoad</code> function):</p>
<pre class="brush: cpp; title: ; notranslate">
#import &quot;ViewController.h&quot;
#import &lt;Cordova/CDVViewController.h&gt;

@interface ViewController ()

@end

@implementation ViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    CDVViewController* viewController = [CDVViewController new];
    viewController.view.frame = CGRectMake(0, 40, 320, 450);
    [self.view addSubview:viewController.view];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}

- (void)dealloc {
    [super dealloc];
}
@end
</pre>
<div class='et-box et-info'>
					<div class='et-box-content'>Since we added the above code to create a new <code>CDVViewController</code> into our main <code>ViewController</code>, we could reuse this class anywhere in our application and it will automatically include the Cordova subview. In the storyboard file in XCode (the UI environment), you can actually set the class of any given View Controller object to <strong>ViewController</strong> and you will get a new <strong>Cordova WebView</strong> subview component automatically due to this code. You can simply set the class to it if it&#8217;s not selected already in the <strong>Identity Inspector</strong> as shown here:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-14-at-1.32.14-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/Screen-Shot-2012-11-14-at-1.32.14-PM.png" alt="" title="Screen Shot 2012-11-14 at 1.32.14 PM" width="262" height="382" class="aligncenter size-full wp-image-4890" /></a></div></div>
<p>In my sample application you can see it when you press the <strong>Open a new Cordova WebView</strong> button. You could choose to add this code wherever you need it, this is just one example for simple illustration. </p>
<h3>Sample Application</h3>
<p>In the first screenshot below, the header navigator and tab bar at the bottom (with badge), and the second view with all the text and controls are actually native iOS controls, whereas the middle embedded view with the button list is an embedded <strong>Cordova WebView</strong> containing HTML/JS to interact with the native <a href="http://docs.phonegap.com/en/2.2.0/index.html">Cordova/PhoneGap APIs</a> to retrieve contacts, use the camera, etc. </p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/native-embed11.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/native-embed11.png" alt="" title="native-embed1" width="300" height="584" class="aligncenter size-full wp-image-4865" /></a></p>
<p>If you&#8217;re familiar with <a href="http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_4_2.html">Storyboarding in XCode for iOS</a>, the Storyboard shows an overview and flow of the application from the native perspective, so you can see the parts which are iOS Native controls versus the other buttons etc that were included from the HTML/JS as part of the <strong>Cordova WebView</strong>:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/xcode6.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/xcode6.png" alt="" title="xcode6" width="650" height="269" class="aligncenter size-full wp-image-4884" /></a></p>
<p>In the next screenshot you can see how we can interact with the Cordova/PhoneGap APIs for native functions like grabbing contacts right there inside our native application:<br />
<a href="http://devgirl.org/wp-content/uploads/2012/11/native-embed21.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/native-embed21.png" alt="" title="native-embed2" width="300" height="598" class="aligncenter size-full wp-image-4866" /></a></p>
<p>This next view is all native iOS controls (see storyboard), but includes a button to pop up a new view that uses the same ViewController class and will have the embbeded Cordova subview:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/11/xcode3.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/xcode3.png" alt="" title="xcode3" width="300" height="578" class="aligncenter size-full wp-image-4869" /></a></p>
<p>And lastly is our next view from the button pop-up that shows how another view will also have the embedded Cordova WebView:<br />
<a href="http://devgirl.org/wp-content/uploads/2012/11/xcode41.png"><img src="http://devgirl.org/wp-content/uploads/2012/11/xcode41.png" alt="" title="xcode4" width="300" height="598" class="aligncenter size-full wp-image-4873" /></a></p>
<p>Grab the <a href="https://github.com/hollyschinsky/NativeAppEmbedWebView">sample application from my github account</a> and give it a whirl. </p>
<p>There&#8217;s an <a href="http://www.infil00p.org/advanced-tutorial-using-cordovawebview-on-android/">advanced tutorial dedicated to embedding PhoneGap for Android here</a>, so be sure to check that out too! </p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2012%2F11%2F15%2Fembed-cordovaphonegap-in-your-native-ios-app%2F&amp;title=Tutorial%3A%20Embed%20PhoneGap%20as%20a%20Subview%20in%20your%20Native%20iOS%20Application" id="wpa2a_16"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2012/11/15/embed-cordovaphonegap-in-your-native-ios-app/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Tutorial: Android Push Notifications with PhoneGap</title>
		<link>http://devgirl.org/2012/10/25/tutorial-android-push-notifications-with-phonegap/</link>
		<comments>http://devgirl.org/2012/10/25/tutorial-android-push-notifications-with-phonegap/#comments</comments>
		<pubDate>Thu, 25 Oct 2012 18:58:22 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Cordova]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=4772</guid>
		<description><![CDATA[My last post covered push notifications with PhoneGap on Apple devices, but I also wanted to cover push notifications with PhoneGap on Android for those developing cross platform applications. I found that I was able to get my notifications working much faster on Android comparatively. Google Cloud Messaging Android push notifications are available via the [...]]]></description>
				<content:encoded><![CDATA[<p>My <a href="http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/">last post</a> covered push notifications with PhoneGap on Apple devices, but I also wanted to cover push notifications with PhoneGap on Android for those developing cross platform applications. I found that I was able to get my notifications working much faster on Android comparatively. </p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/google_cloud.jpeg"><img src="http://devgirl.org/wp-content/uploads/2012/10/google_cloud.jpeg" alt="" title="google_cloud" width="300" height="205" class="alignleft size-full wp-image-4785" /></a><br />
<h2>Google Cloud Messaging</h3>
<p>Android push notifications are available via the <a href="http://developer.android.com/guide/google/gcm/index.html"><strong>Google Cloud Messaging &#8211; GCM</strong></a> service (similar to <a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html">Apple&#8217;s Push Notification Service</a>). Previously they were supported through <a href="https://developers.google.com/android/c2dm/"><strong>C2DM</strong></a> (Cloud to Device Messaging framework) but that API has since been deprecated and the Google Cloud Messaging services adds enhancements above and beyond what C2DM offered. There&#8217;s a <a href="https://github.com/marknutter/GCM-Cordova"><strong>Cordova/PhoneGap plugin</strong></a> available to aid in working with the Google Cloud Messaging service. The message size allotment for the GCM payload is 4kb (String data only), noticeably bigger than the Apple Push Notification requirements of 256 bytes. There&#8217;s an article about the types of messages that can be sent in detail <a href="http://cloud.dzone.com/articles/google-cloud-messaging-payload-0"><strong>here</strong></a>. Also, I suggest you look over the documentation for using this service in general <a href="file://localhost/Users/hollyschinsky/android-sdks/docs/guide/google/gcm/index.html"><strong>here</strong></a> when building your application, there are a lot of details I will not cover in this post. Some points I wanted to highlight from that article are:</p>
<ul>
<li>GCM makes no guarantees about delivery or the order of messages.</li>
<li>An Android application on an Android device doesn&#8217;t need to be running to receive messages. The system will wake up the Android application via Intent broadcast when the message arrives, as long as the application is set up with the proper broadcast receiver and permissions.</li>
<li>It does not provide any built-in user interface or other handling for message data. GCM simply passes raw message data received straight to the Android application, which has full control of how to handle it. For example, the application might post a notification, display a custom user interface, or silently sync data.</li>
</ul>
<h3>Steps</h3>
<p>The steps for setting up push notifications in your Android application are:</p>
<ol>
<li>Create a new Android Cordova project either via the <a href="http://docs.phonegap.com/en/2.1.0/guide_command-line_index.md.html">command line tools</a> or <a href="http://docs.phonegap.com/en/2.1.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android">Eclipse</a> (command line recommended)
<li>Download the <a href="https://github.com/marknutter/GCM-Cordova">GCM Cordova Plugin</a></li>
<li>Follow the steps in the plugin&#8217;s Readme
<ul>
<li>Don&#8217;t forget to setup your Google Cloud Messaging Account as noted in the readme and note your project id located in the URL. For instance the number in bold below is the id you need to send in the <strong><em>register()</em></strong> function:
<p>https://code.google.com/apis/console/?pli=1#project:<strong>824841663942</strong></p>
<li>Don&#8217;t forget to change the following to use your GCM project id (from the step above)
<pre class="brush: java; title: ; notranslate">
                           window.GCM.register(&quot;your_sender_id&quot;, &quot;GCM_Event&quot;, GCM_Success, GCM_Fail );
                       </pre>
<div align="center">becomes</div>
<pre class="brush: java; title: ; notranslate">
                           window.GCM.register(&quot;824841663942&quot;, &quot;GCM_Event&quot;, GCM_Success, GCM_Fail );
                       </pre>
</li>
</ul>
</li>
<li>Add code handling for the actions to take when the application receives a message while open or not (ie: display a popup alert, status bar notification etc).<br />
        <strong>Note: </strong>The plugin handles registering with GCM and has methods for receiving a message, however it does not actually provide the notification code itself, this is something you need to add. Read on further for how to add native code to produce a status bar notification.</li>
</ol>
<p>If you need more information about GCM project creation, specific steps can be found <a href="https://developers.google.com/console/help/#creatingdeletingprojects">here</a>.</p>
<div class='et-box et-download'>
					<div class='et-box-content'>The plugin includes a sample project already setup to register for push notifications (includes the AndroidManifest.xml changes and plugin configuration already), all you have to do is edit the CORDOVA_GCM_script.js file to use your GCM sender/project id in the <strong>register</strong> function and you can run it immediately or use this project as a reference while making the changes to your own.</div></div>
<p>If you prefer to use Eclipse for your editing, you can simply import your existing Android project that you just created above (or the sample included in the plugin) and start working from there. Choose File | New | Project, then you will see the following dialog, where you will select <strong>Android Project from Existing Code as follows</strong>:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-24-at-5.40.33-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-24-at-5.40.33-PM.png" alt="" title="Eclipse Import" width="525" height="499" class="aligncenter size-full wp-image-4780" /></a></p>
<h2>Running the Sample Application</h2>
<p>When you run the sample code from the plugin, it will automatically try to register your device. If registration is successful, you should see a message containing the registration token id as I circled below in the screenshot of mine running on my Galaxy Tablet:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/androidregistered-ss-copy.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/androidregistered-ss-copy.png" alt="" title="androidregistered-ss copy" width="650" height="406" class="aligncenter size-full wp-image-4804" /></a></p>
<p>You should also see the following trace in your console:</p>
<p><code>10-24 18:24:20.720: V/GCMReceiver:onRegistered(21989): Registration ID arrived!<br />
10-24 18:24:20.730: V/GCMReceiver:onRegisterd(21989): {"regid":"APA91bFobAwM7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEdtCDfKoOZqNPsfg","event":"registered"}<br />
10-24 18:24:20.730: V/GCMPlugin:sendJavascript(21989): javascript:GCM_Event({"regid":"APA91bFobAwM7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEdtCDfKoOZqNPsfg","event":"registered"})</code></p>
<p>Once you have obtained a registration id as above, you can write server code (see the section below on using Node.JS code to send a message to your application) or use a service like <a href="http://www.urbanairship.com">Urban Airship</a> or <a href="http://www.pushwoosh.com">PushWoosh</a> to start sending notifications. When a message is received, you will see additional text displayed as shown in the screenshot below:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/message-rcvd-ss.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/message-rcvd-ss.png" alt="" title="message-rcvd-ss" width="650" height="406" class="aligncenter size-full wp-image-4792" /></a></p>
<p>At this point though, the plugin does not contain anything more to actually show a status bar notification or otherwise notify you. The next section covers how you can add some additional code to it for showing a status bar notification when the message is received. </p>
<h2>Status Bar Notification</h2>
<p>Since the plugin simply receives the message (whether running or not) but doesn&#8217;t do anything with it from there, you have various choices for what you could do with it. One common thing is to show a message in the native status bar. Note that on iOS the process is different and the notification is automatically shown, but on Android you have to explicitly code for it. You could use the <a href="https://github.com/phonegap/phonegap-plugins/tree/master/Android/StatusBarNotification">Cordova StatusBarNotification plugin</a> along with this one, or if you want a faster solution, you could simply add the following native Java code into your<strong> GCMIntentService.java</strong> <strong><em>onMessage()</em></strong> function:</p>
<pre class="brush: java; title: ; notranslate">
          String message = extras.getString(&quot;message&quot;);
    	  String title = extras.getString(&quot;title&quot;);
    	  Notification notif = new Notification(android.R.drawable.btn_star_big_on, message, System.currentTimeMillis() );
    	  notif.flags = Notification.FLAG_AUTO_CANCEL;
    	  notif.defaults |= Notification.DEFAULT_SOUND;
    	  notif.defaults |= Notification.DEFAULT_VIBRATE;

    	  Intent notificationIntent = new Intent(context, TestSampleApp.class);
    	  notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    	  PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
    	  
    	  notif.setLatestEventInfo(context, title, message, contentIntent);
    	  String ns = Context.NOTIFICATION_SERVICE;
          NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
          mNotificationManager.notify(1, notif);
</pre>
<p>Also, don&#8217;t forget to add these imports at the top of the file to support the above code:</p>
<pre class="brush: java; title: ; notranslate">
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
</pre>
<div class='et-box et-warning'>
					<div class='et-box-content'>Be sure to replace <em>YourActivityClassName.class</em> with the name of your stub class that extends <strong>DroidGap</strong>. For instance, in the sample project it is called <strong>MainActivity</strong>.</div></div>
<p>The above code sets the notification to include a star icon, vibration and the default sound. An example of it running on my Android Galaxy Tablet is shown below (circled in red).<br />
<a href="http://devgirl.org/wp-content/uploads/2012/10/android-push-screenshot1.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/android-push-screenshot1.png" alt="" title="android-push-screenshot" width="650" height="406" class="aligncenter size-full wp-image-4797" /></a></p>
<p>When you click on the notification, the app will open and look like the following, showing that a message was in fact received:<br />
<a href="http://devgirl.org/wp-content/uploads/2012/10/message-rcvd-ss.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/message-rcvd-ss.png" alt="" title="message-rcvd-ss" width="650" height="406" class="aligncenter size-full wp-image-4792" /></a><br />
<div class='et-box et-info'>
					<div class='et-box-content'>Status bar notifications will be displayed differently depending on the type of device. Some Android devices will show them at the top versus  at the bottom as shown in my screenshots&#8230;</div></div></p>
<h2>Sending a message with <strong>node-gcm</strong></a></h2>
<p>There&#8217;s a <a href="http://nodejs.org/">Node.js</a> library for sending notifications through Google Cloud Messaging as there was for Apple&#8217;s Push Notification Service as I showed in my last post. It&#8217;s called <a href="https://github.com/h2soft/node-gcm"><strong>node-gcm</strong></a>, and below is the code I used to send my device a message (keys changed <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). In the <strong>Sender</strong> parameter you need to specify the API key that Google gave you when you registered for the Google Cloud Messaging service. You received two API keys, a browser and server key, either should work here, but if one does not, try the other <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ! You also need to specify the token returned to your application when you registered using the plugin above. This is the registration id that was printed to the screen and console when you ran the application and called the GCM <strong>register</strong> function. </p>
<pre class="brush: jscript; title: ; notranslate">
var gcm = require('node-gcm');

var message = new gcm.Message();
var sender = new gcm.Sender('AIzaSyCDx8v9R0fMsAsjoAffF-P3FCFWXlvwKgL');
var registrationIds = [];

message.addData('title','My Game');
message.addData('message','Your turn!!!!');
message.addData('msgcnt','1');
message.collapseKey = 'demo';
message.delayWhileIdle = true;
message.timeToLive = 3;

// At least one token is required - each app will register a different token
registrationIds.push('APA91bFobAwN7P3Okxy2al8RI12VcJFUS-giXWTOoWXIObtSPOE1h7FuH1VPLBPgshDI_Fp7aIYVET-ssvGUErlWYA0cKPGhoXT1daqyDsEfem9ZtgZNRhQFv7kLCIVSigYlpMluToPiSHSsFSEdtCDfKoOZqNPgfs');

/**
 * Parameters: message-literal, registrationIds-array, No. of retries, callback-function
 */
sender.send(message, registrationIds, 4, function (result) {
    console.log(result);
});
/** Use the following line if you want to send the message without retries
sender.sendNoRetry(message, registrationIds, function (result) { console.log(result); });
**/
</pre>
<div class='et-box et-warning'>
					<div class='et-box-content'>You need to set the name of the title and message keys explicitly to <em>title</em> and <em>message</em> as the application plugin code is looking for that in <strong>GCMIntentService.java</strong>:</p>
<pre class="brush: java; title: ; notranslate">
Bundle extras = intent.getExtras();
    if (extras != null) {
        try {
          String title = extras.getString(&quot;title&quot;);
          String message = extras.getString(&quot;message&quot;);
          ....
        }
     }
</pre></div></div>
<p><strong>Collapse Key</strong><br />
According to the <a href="http://developer.android.com/training/cloudsync/gcm.html">Android developer documentation</a>, when you define a collapse key, it will only deliver the last one with a given collapse key, therefore saving the user from becoming &#8216;over-notified&#8217; such as in the case of sports scores for example.</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/notification-open-ss.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/notification-open-ss.png" alt="" title="notification-open-ss" width="650" height="406" class="aligncenter size-full wp-image-4793" /></a></p>
<p>Also, note that these status bar notifications will be shown in the expanded list (if not dismissed yet) such as in the following:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/notification-list-copy.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/notification-list-copy.png" alt="" title="notification-list copy" width="650" height="406" class="aligncenter size-full wp-image-4794" /></a></p>
<h3>Other Plugin Options</h3>
<p>Lastly, I wanted to point out that if you are googling about Cordova push notification plugins for Android, you may also come across another one <strong><a href="https://github.com/shaders/phonegap-cordova-push-notifications/tree/master/Android">here</a></strong>. This one is supposed to be more specific to using notifications from <a href="http://www.pushwoosh.com">PushWoosh</a>, which I will cover in a future post with a sample. The plugin API more closely resembles the iOS Cordova PushNotification plugin, and interestingly enough still worked in receiving push notifications from my Node.js service completely outside of the PushWoosh service when I tested it (and I did not have to add the native Java code shown above to show the status bar notification) so I wanted people to be aware of it in case they wanted to try this plugin as well. </p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2012%2F10%2F25%2Ftutorial-android-push-notifications-with-phonegap%2F&amp;title=Tutorial%3A%20Android%20Push%20Notifications%20with%20PhoneGap" id="wpa2a_18"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2012/10/25/tutorial-android-push-notifications-with-phonegap/feed/</wfw:commentRss>
		<slash:comments>86</slash:comments>
		</item>
		<item>
		<title>Tutorial: Apple Push Notifications with PhoneGap &#8211; Part 1</title>
		<link>http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/</link>
		<comments>http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/#comments</comments>
		<pubDate>Fri, 19 Oct 2012 15:37:34 +0000</pubDate>
		<dc:creator>Holly Schinsky</dc:creator>
				<category><![CDATA[Cordova]]></category>
		<category><![CDATA[Mobile Development]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[APN]]></category>
		<category><![CDATA[Apple Push Notification]]></category>
		<category><![CDATA[Cordova PushNotification]]></category>
		<category><![CDATA[Cordova PushNotification Plugin]]></category>
		<category><![CDATA[PhoneGap Push Notification]]></category>
		<category><![CDATA[Push Notification]]></category>
		<category><![CDATA[PushNotification Plugin]]></category>

		<guid isPermaLink="false">http://devgirl.org/?p=4643</guid>
		<description><![CDATA[This is part 1 of a new series to help explain how to set up and use Apple Push Notifications (APNs) in your mobile applications. Push notifications are different than local notifications in that they are coming from a 3rd party server to inform the user of something, versus a local notification which is scheduled [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://devgirl.org/wp-content/uploads/2012/10/apple-push-notification-service1.jpeg"><img src="http://devgirl.org/wp-content/uploads/2012/10/apple-push-notification-service1.jpeg" alt="" title="apple-push-notification-service" width="195" height="212" class="alignleft size-full wp-image-4686" /></a></p>
<p>This is part 1 of a new series to help explain how to set up and use <a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html">Apple Push Notifications (APNs)</a> in your mobile applications. Push notifications are different than local notifications in that they are coming from a 3rd party server to inform the user of something, versus a local notification which is scheduled by the application to run on the device itself without any server interaction. For instance you may receive a push notification from <a href="https://www.facebook.com/">Facebook</a> notifying you that someone has added you as a friend, or if you are a <a href="http://www.wordswithfriends.com/">Words With Friends</a> player you may receive a push notification indicating it&#8217;s your turn. An example of a local notification would be an alert popping up at a certain time or interval as a reminder from a to do application where you set a date/time to a task and the alert pops up to remind you at that specified time. To the end user they may appear the same in that they both pop alerts, can have sounds associated etc, but they are very different from a development perspective.</p>
<p>There are Cordova/PhoneGap plugins to do both <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/LocalNotifications">local</a> and <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification">push notifications</a> for iOS, but this series will focus on push notifications. If you&#8217;re wondering about Android, there is a concept of push notifications but the setup and process is a bit different and will be covered in a later post. </p>
<p>The process to get started with setting up APNs can be a bit intimidating initially but it&#8217;s worth taking the time to do so as the use cases are endless. This series is intended to help you understand the whole process including setup and what is occurring on both the application and server-side with <a href="https://github.com/hollyschinsky/PGPushNotificationSample">sample code</a> to get you started quickly.</p>
<div align="center">
<h3>APN Workflow Overview</h3>
<p>
(credit to <a href="http://www.raywenderlich.com/">Ray Wenderlich</a>)<br />
<a href="http://devgirl.org/wp-content/uploads/2012/10/Push-Overview-467x500.jpeg"><img src="http://devgirl.org/wp-content/uploads/2012/10/Push-Overview-467x500.jpeg" alt="" title="Push-Overview-467x500" width="467" height="500" class="aligncenter size-full wp-image-4737" /></a></p>
<p>(credit to <a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW9">Apple Inc</a>)<br />
<a href="http://devgirl.org/wp-content/uploads/2012/10/remote_notif_multiple1.jpeg"><img src="http://devgirl.org/wp-content/uploads/2012/10/remote_notif_multiple1.jpeg" alt="" title="remote_notif_multiple" width="416" height="231" class="aligncenter size-full wp-image-4713" /></a></p>
</div>
<h3>Explanation of Workflow</h3>
<ul>
<li>Upon launch, your application communicates with the <a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html">Apple Push Notification Service</a> to authorize it to receive push notifications.</li>
<li>Apple responds with a unique token that must be used in all future communications to receive push notifications.</li>
<li>Your application sends that token to a 3rd party server (your own or some other provider like Urban Airship for instance), that will store it for later events when the application needs to be notified. </li>
<li>When an event occurs where your application needs to receive a notification, the server script reads in the unique device token and sends a message with a pre-defined structure to the Apple Push Notification Services which then securely sends to your device. The structure may include a message, sound and badge number to display on the application launch icon or any combination of the three.</li>
</ul>
<h3>High Level How-To (details to follow):</h3>
<ol>
<li><strong>iOS Provisioning Portal</strong></li>
<ul>
<li>Create a new App ID with push notifications enabled and an SSL Certificate associated</li>
<li>Create a new provisioning file for the above App ID and download it</li>
<li>Drag new provisioning file into XCode (or via XCode Organizer)</li>
<li>Associate new provisioning file with your Project in the Code Signing Options</li>
</ul>
<li><strong>Cordova/PhoneGap Plugin Setup</strong></li>
<ul>
<li>Download Cordova Plugin for PushNotifications</li>
<li>Add PushNotification plugin key and value to Cordova.plist</li>
<li>Drag PushNotification folder to XCode Plugins Folder (create groups for any added folders) &#8211; only the PushNotification.m and PushNotification.h are needed here for the native, see next step for the PushNotification.js client side</li>
<li>In Finder, copy the <strong>PushNotification.js </strong>file from your downloaded plugin into the existing www folder</li>
<li>Add a script tag to refer to the new <strong>PushNotification.js</strong></li>
<li>Add methods to the <strong>AppDelegate.m</strong> (under Classes) to handle push notification events and code for handling launch of application from a push notification</li>
</ul>
<li><strong>Client Side Application Handling</strong></li>
<ul>
<li>Add code to register the user&#8217;s device</li>
<li>Add code to listen for notification events when app is active</li>
<li>Add code for badge management (clear on relaunch from notification etc)</li>
<li>Add code to check user&#8217;s notification status &#8211; which options do they have set for this application specifically (they can control notification type, badge/alert/sound)</li>
<li>Add code to get pending notifications (ie: if app is opened from the push notification, we need to access that notification to get the data passed in to see if updates are needed etc)
<li>Include resources in your project for custom sounds or launch images to be associated with your push notification</li>
</ul>
<li><strong>Server Side Handling (Optional)</strong></li>
<ul>
<li>Specify the URL to the Apple Push Notification Service gateway (sandbox or production)</li>
<li>Ensure proper certificates available on server</li>
<li>Specify any custom sounds</li>
<li>Special any launch images</li>
<li>Save registered device id&#8217;s in a database</li>
</ul>
</ol>
<h3>SSL Certificates and Provisioning</h3>
<p>The first thing you need to do is set up certificates and provisioning to provide a secure connection for communication between servers and your application. Don&#8217;t let this step scare you, it&#8217;s not that bad once you do it <img src='http://devgirl.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . There&#8217;s a great article <a href="http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12">here that documents this process with screenshots and details</a> that you should use for this step. In the next paragraph I attempt to put words to exactly what it is you&#8217;re doing and why for those that want to understand better, but feel free to skip that paragraph if you just want to go through the setup <a href="http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12">using the article</a>. </p>
<div class='et-box et-shadow'>
					<div class='et-box-content'><h4>Certificates and Provisioning Explanation</h4>
<p>Basically your application needs to be enabled for push notifications through the Apple iOS Provisioning Portal via an App ID (<strong><em>com.mysite.myapp</em></strong>) and signed with a provisioning profile that includes this push enabled application identifier. The App ID also needs to be associated with an SSL certificate for communicating securely with Apple&#8217;s Push Notification Server. When you configure the App ID through the portal, a wizard will prompt you to create an SSL certificate that will be associated with your App ID and used for that purpose. Having the association with the App ID will will ensure the notifications sent from your server to Apple&#8217;s APN Server will then be sent to *just* the application with that matching id. Once the certificate process is complete you will need to download a new provisioning file for this new App ID containing the enabled push notifications. You then drag it into XCode and make sure it is the provisioning profile that is selected for your application in the Code Signing screen (under <strong>Build Settings</strong> for your project).</div></div>
<h3>Setting up your Application</h3>
<p>Now that you&#8217;re ready to start coding your HTML/JavaScript/PhoneGap application, go through the following steps to set it up:</p>
<div class='et-box et-info'>
					<div class='et-box-content'>This article assumes you know how to create a project including <a href="http://phonegap.com">PhoneGap/Cordova</a>, if not, please refer to the <a href="http://docs.phonegap.com/en/2.1.0/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS">Getting Started tutorials on the website</a>).</div></div>
<ol>
<li>Get the latest <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification">PhoneGap Push Notifications plugin</a> from GitHub.</li>
<li>Drag and drop the <strong>PushNotification</strong> folder to the <strong>Plugins folder in XCode</strong> and select the &#8220;Create groups for any added folders&#8221; as the copy option as shown in the screenshot.</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-16-at-5.58.09-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-16-at-5.58.09-PM.png" alt="" title="Screen Shot 2012-10-16 at 5.58.09 PM" width="695" height="452" class="aligncenter size-full wp-image-4700" /></a></p>
<li>Go <strong><em>out of XCode and into Finder</em></strong> and copy the <strong><em>PushNotification.js</em></strong> file into your <strong>www</strong> folder (or in a subfolder called <strong>plugins</strong> underneath the www folder to keep it cleaner). It will automatically show up in XCode for you. You cannot drag a file into XCode into this folder because of the way that it&#8217;s set up as a folder reference (icon is blue). See the <a href="https://github.com/hollyschinsky/PGPushNotificationSample/tree/master/platforms/ios">sample project for further reference</a>.
<li>Add a script tag to refer to the <strong><em>PushNotification.js</em></strong> file in your HTML file such as:
<pre class="brush: xml; title: ; notranslate">
&lt;script src=&quot;js/PushNotification.js&quot;&gt;&lt;/script&gt;
</pre>
<p><div class='et-box et-info'>
					<div class='et-box-content'>Rather than adding the <strong>PushNotification.js</strong> file directly into the <strong>www</strong> root folder in your Finder, you may want to create a <em><strong>plugins</strong></em> subfolder to contain them in case you end up using others. If you do create that subfolder than your script tag needs to reference the file as below in your HTML instead: </p>
<pre class="brush: xml; title: ; notranslate">
&lt;script src=&quot;js/plugins/PushNotification.js&quot;&gt;&lt;/script&gt;
</pre></div></div>
</li>
<li>Add the plugin key and value to your <strong>Cordova.plist</strong> (found under your project root Resources folder)</li>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-16-at-6.05.43-AM.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-16-at-6.05.43-AM.png" alt="" title="Plugin Added" width="533" height="444" class="aligncenter size-full wp-image-4655" /></a>
</ol>
<p>The <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification">Cordova PushNotification plugin</a> gives you a nice JavaScript API you can use from your HTML/JS files to interact with the underlying native code for handling the registration and receiving of push notifications. Some of the functions provided are listed here:<br />
<strong></p>
<ul>
<li>registerDevice()</li>
<li>setApplicationIconBadgeNumber()</li>
<li>getRemoteNotificationStatus()</li>
<li>getPendingNotifications()</li>
</ul>
<p></strong></p>
<p>To use it though, you first need to add some things to the native application code to bridge to the specific push notification code. The <a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html">AppDelegate class</a> for an application (located under your project Classes folder) implements the handlers for application-wide events, such as application launch, termination and more. There are also events available for handling notifications. A list of them can be found here in the <a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html">Handling Notifications reference</a>. These methods are not implemented by default though, so in order to support them we need to add the code handlers and have them delegate to our included <strong><a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification/PushNotification.m">PushNotification.m</a></strong> class in our plugin code. The code to add is shown in the <a href="https://github.com/phonegap/phonegap-plugins/blob/master/iOS/PushNotification/README.md">README</a> for the plugin but I&#8217;ll paste it here as well for further reference. You&#8217;re basically handling three events with it:<br />
<strong><em></p>
<ul>
<li>didReceiveRemoteNotification</li>
<li>didRegisterForRemoteNotificationsWithDeviceToken</li>
<li>didFailToRegisterForRemoteNotificationsWithError</li>
</ul>
<p></em></strong><br />
Add the following code block to your <strong>AppDelegate.m</strong> class before the <strong>@end </strong>to handle the notification events:</p>
<pre class="brush: cpp; title: ; notranslate">
/* START BLOCK */
#pragma PushNotification delegation

- (void)application:(UIApplication*)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    PushNotification* pushHandler = [self.viewController getCommandInstance:@&quot;PushNotification&quot;];
    [pushHandler didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication*)app didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
    PushNotification* pushHandler = [self.viewController getCommandInstance:@&quot;PushNotification&quot;];
    [pushHandler didFailToRegisterForRemoteNotificationsWithError:error];
}

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
    PushNotification* pushHandler = [self.viewController getCommandInstance:@&quot;PushNotification&quot;];
    NSMutableDictionary* mutableUserInfo = [userInfo mutableCopy];

    // Get application state for iOS4.x+ devices, otherwise assume active
    UIApplicationState appState = UIApplicationStateActive;
    if ([application respondsToSelector:@selector(applicationState)]) {
        appState = application.applicationState;
    }

    [mutableUserInfo setValue:@&quot;0&quot; forKey:@&quot;applicationLaunchNotification&quot;];
    if (appState == UIApplicationStateActive) {
        [mutableUserInfo setValue:@&quot;1&quot; forKey:@&quot;applicationStateActive&quot;];
        [pushHandler didReceiveRemoteNotification:mutableUserInfo];
    } else {
        [mutableUserInfo setValue:@&quot;0&quot; forKey:@&quot;applicationStateActive&quot;];
        [mutableUserInfo setValue:[NSNumber numberWithDouble: [[NSDate date] timeIntervalSince1970]] forKey:@&quot;timestamp&quot;];
        [pushHandler.pendingNotifications addObject:mutableUserInfo];
    }
}
/* STOP BLOCK */
</pre>
<p>The above code essentially creates a reference to our <strong>PushNotification</strong> class, sets or reads some values (not going into detail here to keep this less complicated), and calls different methods with parameters depending on the event that occurred.</p>
<div class='et-box et-info'>
					<div class='et-box-content'>Don&#8217;t worry if you don&#8217;t know any Objective-C or this seems complicated at this point, <a href="https://github.com/hollyschinsky/PGPushNotificationSample">a sample project</a> has been included here for reference!</div></div>
<p>The last thing you need to do is add a code fragment into the <strong><em>didFinishLaunchingWithOptions</em></strong> method in that same <strong>AppDelegate.m</strong> class to handle opening the application from a notification (and adding the received object to the <strong><em>pendingNotifications</em></strong> for later retrieval). Add this block right before the end <code>return YES</code>:</p>
<pre class="brush: cpp; title: ; notranslate">
    /* Handler when launching application from push notification */
    // PushNotification - Handle launch from a push notification
    NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    if(userInfo) {
        PushNotification *pushHandler = [self.viewController getCommandInstance:@&quot;PushNotification&quot;];
        NSMutableDictionary* mutableUserInfo = [userInfo mutableCopy];
        [mutableUserInfo setValue:@&quot;1&quot; forKey:@&quot;applicationLaunchNotification&quot;];
        [mutableUserInfo setValue:@&quot;0&quot; forKey:@&quot;applicationStateActive&quot;];
        [pushHandler.pendingNotifications addObject:mutableUserInfo];
    }
/* end code block */
</pre>
<h2>PushNotification Plugin &#8211; JavaScript APIs</h2>
<p>Now that you have the project setup complete including the native Objective-C handlers above, you can actually start coding with the Cordova PushNotification JavaScript interfaces. Below is further detail about some of them and examples of interacting with then in your code. <strong>Note:</strong> there are others that are available but not covered specifically yet in this post. </p>
<p><strong>Register Device</strong><br />
The <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification">PhoneGap PushNotification plugin</a> offers a <strong><em>registerDevice()</em></strong> API to register your application with Apple&#8217;s Push Notification Service to receive push notifications. In the function you specify exactly which types of notifications are enabled (alerts/badges/sounds). The result is a unique device token that can then be used by the server-side to send the notification to that device.<br />
<div class='et-box et-info'>
					<div class='et-box-content'>Apple recommends you register your application for push notifications on the device every time it&#8217;s run since tokens can change. The documentation says: &#8216;By requesting the device token and passing it to the provider every time your application launches, you help to ensure that the provider has the current token for the device. If a user restores a backup to a device other than the one that the backup was created for (for example, the user migrates data to a new device), he or she must launch the application at least once for it to receive notifications again. If the user restores backup data to a new device or reinstalls the operating system, the device token changes. Moreover, never cache a device token and give that to your provider; always get the token from the system whenever you need it.&#8217;</div></div></p>
<p>An example of using the <strong><em>registerDevice()</em></strong> function is included in the <a href="https://github.com/hollyschinsky/PGPushNotificationSample/blob/master/platforms/ios/www/js/index.js">sample project</a> and is also shown below:</p>
<pre class="brush: jscript; title: ; notranslate">
        var pushNotification = window.plugins.pushNotification;
        pushNotification.registerDevice({alert:true, badge:true, sound:true}, function(status) {
            app.myLog.value+=JSON.stringify(['registerDevice status: ', status])+&quot;\n&quot;;
            app.storeToken(status.deviceToken);
        });
</pre>
<p>Once the above code is in place and your application is run, you will receive an alert like the following prompting if it&#8217;s ok to receive push notifications (this results in a setting that can be modified in your device settings as needed):<br />
<a href="http://devgirl.org/wp-content/uploads/2012/10/twitter-push-notifications.jpeg"><img src="http://devgirl.org/wp-content/uploads/2012/10/twitter-push-notifications.jpeg" alt="" title="twitter-push-notifications" width="280" height="244" class="aligncenter size-full wp-image-4697" /></a></p>
<p><strong>Get Pending Notifications</strong><br />
Pending notifications are those notifications that are received while the application was not active. When the application is launched you will want to retrieve them so you can handle the data sent to you as needed. The <em>getPendingNotifications()</em> function is available in the API for that purpose. Below is some example code:</p>
<pre class="brush: jscript; title: ; notranslate">
        var pushNotification = window.plugins.pushNotification;
        pushNotification.getPendingNotifications(function(notifications) {
            app.myLog.value+=JSON.stringify(['getPendingNotifications', notifications])+&quot;\n&quot;;
            console.log(JSON.stringify(['getPendingNotifications', notifications]));
        });
        </pre>
<p><strong>Get Notification Status</strong><br />
        This method will return type and which notifications are enabled (alert, sound, badge). </p>
<pre class="brush: jscript; title: ; notranslate">
        var pushNotification = window.plugins.pushNotification;
        pushNotification.getRemoteNotificationStatus(function(status) {
            app.myLog.value+=JSON.stringify(['Registration check - getRemoteNotificationStatus', status])+&quot;\n&quot;;
        });
        </pre>
<p><strong>Set Badge Number</strong><br />
You will likely need to set the badge number on the application icon as you process the notifications, for instance if you open from a push notification just received, you may want to decrement or clear it. Setting the badge number to 0 will remove or clear the badge as shown below.</p>
<pre class="brush: jscript; title: ; notranslate">
        var pushNotification = window.plugins.pushNotification;
        app.myLog.value+=&quot;Clear badge... \n&quot;;
        pushNotification.setApplicationIconBadgeNumber(num);
        </pre>
<h2>Anatomy of an Apple Push Notification</h2>
<p>The maximum size for a notification payload is 256 bytes. If that limit is exceeded, it will be refused. Also note the delivery of notifications is “best effort” and not guaranteed, according to the Apple documentation, so you should not use it for sending critical or sensitive data, only to notify that new data is available. The notification payload is a JSON dictionary object that needs to contain another dictionary identified by the key <strong>aps</strong>. The <strong>aps</strong> dictionary then will contain one or more properties that would specify an alert to display, a number badge to set on the application icon and/or a sound to play when the notification occurs. It&#8217;s also possible to create a custom payload but that is beyond the scope of this post. The alert object itself can contain just a string of text to display, OR a dictionary object with keys for a body, custom action button text to display and a custom launch image that can be set. More specific details about the payload can be found <a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html">here</a>.</p>
<p>Here&#8217;s an example of a simple payload in bytes:<br />
<a href="http://devgirl.org/wp-content/uploads/2012/10/aps_provider_binary.jpeg"><img src="http://devgirl.org/wp-content/uploads/2012/10/aps_provider_binary.jpeg" alt="" title="aps_provider_binary" width="523" height="116" class="aligncenter size-full wp-image-4764" /></a></p>
<p>A typical <strong>aps</strong> dictionary object will contain 3 properties; alert, badge and sound, such as shown in the following output:</p>
<p>    applicationLaunchNotification = 0;<br />
    applicationStateActive = 0;<br />
    <strong>aps = {<br />
        alert =                 {<br />
        &#8220;action-loc-key&#8221; = Play;<br />
            body = &#8220;Your turn!&#8221;;<br />
            &#8220;launch-image&#8221; = &#8220;mysplash.png&#8221;;<br />
        };<br />
        badge = 5;<br />
        sound = &#8220;notification-beep.wav&#8221;;<br />
    };</strong><br />
    messageFrom = Holly;<br />
    timestamp = &#8220;1350416054.782263&#8243;;</p>
<div class='et-box et-warning'>
					<div class='et-box-content'>Any custom sounds or launch images must be contained in the Resources folder in your project (under XCode)your projects Resources folder in XCode. For example in my image below, I have a <strong>notification-beep.wav</strong> and <strong>mysplash.png</strong> specified that I refer to in my push notification coming from the server.</div></div>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-18-at-9.59.41-PM.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/Screen-Shot-2012-10-18-at-9.59.41-PM.png" alt="" title="Screen Shot 2012-10-18 at 9.59.41 PM" width="250" height="512" class="aligncenter size-full wp-image-4710" /></a></p>
<h2>Server-Side Code Handling</h2>
<h3>Simple Server</h3>
<p><strong>Listening for device registration token with Node.js</strong><br />
Below is example code you could use to get started with a server-side solution to handling device token registration which I currently call from <a href="https://github.com/hollyschinsky/PGPushNotificationSample/blob/master/platforms/ios/www/js/index.js">my application sample</a> to show how and at which point you might want to communicate with a 3rd party server to store device tokens after receiving the device token from Apple. Currently it doesn&#8217;t do anything with the token other than show that it and the message were received, but the next step would be to store the users&#8217;s device token and any other information in a database for later use when a push notification needs to be sent (such as shown in the next example). I plan to do a Part 2 series on integrating with MongoDB so check back soon!</p>
<pre class="brush: jscript; title: ; notranslate">
var http = require('http');
var apn = require('apn');
var qs = require('querystring');

var server = http.createServer(function (req, res) {
	if(req.method === &quot;POST&quot;) {
		var fullBody=&quot;&quot;;
	
		req.on('data', function(chunk)	
		{
			fullBody += chunk;
			console.log(&quot;Full body &quot; + fullBody);
		});

		req.on('end', function()
		{
			var data = qs.parse(fullBody);
			console.log(&quot;Token &quot; +data.token);
			console.log(&quot;Message &quot; + data.message);
			var myDevice = new apn.Device(data.token);
			// Now we need to store it! Add code to interface with a db below...

			res.writeHead(200, {&quot;Content-Type&quot;: &quot;text/plain&quot;});
			res.end(&quot;Thank you for registering\n&quot;);
			res.end();
		});
	}
}).listen(8888);
console.log(&quot;Server running at http://127.0.0.1:&quot;+server.address().port);
</pre>
<p><strong>Note:</strong> I&#8217;m simply running this script using <a href="nodejs.org">Node.js</a> on my localhost. When testing from your actual device (since push notifications are not supported in the emulator), you can set up a Manual HTTP Proxy in your device&#8217;s Wi-Fi settings to point to the IP Address of your computer. Go to your Wi-Fi network and scroll to the bottom of the settings to set the Manual Proxy server and port. Here&#8217;s an example of mine:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/wifi.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/wifi.png" alt="" title="wifi" width="250" height="375" class="aligncenter size-full wp-image-4730" /></a></p>
<h3>Sending a Notification with <a href="https://github.com/argon/node-apn">Argon (Node.js API)</a></h3>
<p>Below is an example of some simple code to show how you could use the <a href="https://github.com/argon/node-apn">argon open source Node.js API</a> to send a push notification to a users device. I simply hard-coded my device tokens in for quick testing, but ultimately you would be retrieving them from a database (after being stored above) to use for sending the push notifications. </p>
<pre class="brush: jscript; title: ; notranslate">
var http = require('http');
var apn = require('apn');
var url = require('url');

var myPhone = &quot;d2d8d2a652148a5cea89d827d23eee0d34447722a2e7defe72fe19d733697fb0&quot;;
var myiPad = &quot;51798aaef34f439bbb57d6e668c5c5a780049dae840a0a3626453cd4922bc7ac&quot;;

var myDevice = new apn.Device(myPhone);

var note = new apn.Notification();
note.badge = 1;
note.sound = &quot;notification-beep.wav&quot;;
note.alert = { &quot;body&quot; : &quot;Your turn!&quot;, &quot;action-loc-key&quot; : &quot;Play&quot; , &quot;launch-image&quot; : &quot;mysplash.png&quot;};
note.payload = {'messageFrom': 'Holly'};

note.device = myDevice;

var callback = function(errorNum, notification){
	console.log('Error is: %s', errorNum);
	console.log(&quot;Note &quot; + notification);
}
var options = {
	gateway: 'gateway.sandbox.push.apple.com', // this URL is different for Apple's Production Servers and changes when you go to production
	errorCallback: callback,
	cert: 'PushNotificationSampleCert.pem',                 
	key:  'PushNotificationSampleKey.pem',                 
	passphrase: 'myPassword',                 
	port: 2195,                       
	enhanced: true,                   
	cacheLength: 100                  
}
var apnsConnection = new apn.Connection(options);
apnsConnection.sendNotification(note);
</pre>
<div align="center">
The above code will produce a notification that looks like the following on my device if you have your device <strong>Settings->Notifications->MyAppName </strong>set to <strong><em>Alerts</em></strong>:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/notification-shot.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/notification-shot.png" alt="" title="notification-shot" width="250" height="376" class="aligncenter size-full wp-image-4733" /></a></p>
<p>If you&#8217;re device settings for Alert Style on the application is set to <strong><em>Banners</em></strong>, it will look like this:</p>
<p><a href="http://devgirl.org/wp-content/uploads/2012/10/banner.png"><img src="http://devgirl.org/wp-content/uploads/2012/10/banner.png" alt="" title="banner" width="250" height="376" class="aligncenter size-full wp-image-4734" /></a>
</div>
<div class='et-box et-warning'>
					<div class='et-box-content'><strong>Important Note:</strong> You need to change the .pem files to your cert and private key created in the setup (the ones you ultimately combined into a single .pem with instructions from <a href="http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12">here</a>. Remember you first converted the .cer to a .pem, and then your .p12 to a .pem, those are the two files needed here &#8211; see <a href="https://github.com/argon/node-apn">this readme</a> for more details on argon parameters). In my example, my .pem files are in the same folder as my Node.js code. You can omit the password property if you did not keep a password on them.</div></div>
<div class='et-box et-info'>
					<div class='et-box-content'>There&#8217;s also a PHP Push Notifications API called <a href="http://code.google.com/p/apns-php">APNS-PHP</a> if you prefer to use PHP as your language of choice&#8230;</div></div>
<h3>Sample Project</h3>
<p>I&#8217;ve included <a href="https://github.com/hollyschinsky/PGPushNotificationSample/"><strong>a link to a sample project on GitHub</strong></a> that I created for a reference application since it includes everything discussed above already in place. You can&#8217;t actually use this project out of the box because you have to have your own uniqe App ID and Provisioning files set on your project for it so you are better off starting your own project from scratch and using mine for reference only. I created this project to eventually be cross-platform using the <a href="http://devgirl.org/2012/10/04/cross-platform-phonegap-aka-cordova-project-templates-in-a-jiffy/">cordova-client tool</a>, but currently only iOS is setup so refer to the <strong><a href="https://github.com/hollyschinsky/PGPushNotificationSample/tree/master/platforms/ios">PGPushNotificationSample/platforms/ios</a></strong> path for the iOS specific code. You&#8217;ll find all of the JavaScript functions in the <strong><em><a href="https://github.com/hollyschinsky/PGPushNotificationSample/blob/master/platforms/ios/www/js/index.js">PGPushNotificationSample/platforms/ios/www/js/index.js</a></em></strong> file. I chose straight JavaScript in favor of simplicity. It also does an <strong>XMLHttpRequest</strong> to my simple server code (example shown above) and sends the device token received from the registration. </p>
<p>Check back soon for more posts to come related to this topic!</p>
<h3>Related Links</h3>
<p><a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/WhatAreRemoteNotif/WhatAreRemoteNotif.html">Local versus Push Notifications (in-depth explanation from Apple)</a><br />
<a href="http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html">Apple Push Service Details</a><br />
<a href="http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12" title="Apple Push Notification Services Tutorial by Ray Wenderlich ">Apple Push Notification Services Tutorial by Ray Wenderlich</a><br />
<a href="http://blog.serverdensity.com/how-to-build-an-apple-push-notification-provider-server-tutorial/" title="Apple Push Notifications Provider  Server Tutorial">Apple Push Notifications Provider Server Tutorial</a><br />
<a href="https://github.com/argon/node-apn" title="Argon - Apple Push Notification API in NodeJS">Argon &#8211; Apple Push Notifications API in Node.js</a><br />
<a href="http://code.google.com/p/apns-php/" title="APNS-PHP - Apple Push Notification API for PHP">APNS-PHP &#8211; Apple Push Notifications API for PHP</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fdevgirl.org%2F2012%2F10%2F19%2Ftutorial-apple-push-notifications-with-phonegap-part-1%2F&amp;title=Tutorial%3A%20Apple%20Push%20Notifications%20with%20PhoneGap%20%E2%80%93%20Part%201" id="wpa2a_20"><img src="http://devgirl.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://devgirl.org/2012/10/19/tutorial-apple-push-notifications-with-phonegap-part-1/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
