<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Irrelon Software's Blog]]></title><description><![CDATA[A blog in the world of everything tech, web and mobile application development, new and emerging technologies and daily news.]]></description><link>http://blog.irrelon.com/</link><generator>Ghost 0.11</generator><lastBuildDate>Fri, 07 Jun 2019 21:11:59 GMT</lastBuildDate><atom:link href="http://blog.irrelon.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Aviation Experts Think They Understand Autonomous Driving]]></title><description><![CDATA[<p>Aviation experts recently advised the auto industry to proceed with caution in its attempts to build up autonomous driving technology: (<a href="http://www.investopedia.com/news/aviation-experts-warn-selfdriving-cars-stall-tsla/#ixzz4FmPkUGEw">http://www.investopedia.com/news/aviation-experts-warn-selfdriving-cars-stall-tsla/#ixzz4FmPkUGEw</a>).</p>

<p>Greg Howard from Aviator Man Magazine said, "Cars are exactly the same as planes and because we understand planes really well, we think</p>]]></description><link>http://blog.irrelon.com/aviation-experts-think-they-understand-cars/</link><guid isPermaLink="false">41b419e6-23d2-40bc-8599-527156ade0e9</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Fri, 29 Jul 2016 07:31:44 GMT</pubDate><content:encoded><![CDATA[<p>Aviation experts recently advised the auto industry to proceed with caution in its attempts to build up autonomous driving technology: (<a href="http://www.investopedia.com/news/aviation-experts-warn-selfdriving-cars-stall-tsla/#ixzz4FmPkUGEw">http://www.investopedia.com/news/aviation-experts-warn-selfdriving-cars-stall-tsla/#ixzz4FmPkUGEw</a>).</p>

<p>Greg Howard from Aviator Man Magazine said, "Cars are exactly the same as planes and because we understand planes really well, we think we should have a say about cars and importantly, autonomous technology in cars. Autopilot systems on planes are pretty similar, there are lines in the road just like clouds in the sky and just like the sky, you never know when a BMW or Audi driver will cut you up and you have to be ready to take control in that situation."</p>

<p>Greg went on to say that while he thinks technologies like Tesla's Autopilot are good, they should only be switched on when your car is above 35,000 feet for safety reasons. This is another voice in the growing crowd of people who are backing more regulation for the car industry at a time when properly administered autonomous driving technologies have been proven to have killed zero people so far.</p>

<p>Greg says, "That's already way too many and it may be time to engage a knee jerk reaction that is needed to help save future drivers from themselves, and other aircraft."</p>]]></content:encoded></item><item><title><![CDATA[Tesla Referral Discount]]></title><description><![CDATA[<p><img src="http://www.irrelon.com/images/modelS.jpg" alt="Tesla Model S"></p>

<p>If you happen to be considering purchasing a Tesla (the world's most awesome car) you now have an opportunity to get a £750 / $1,000 discount. Tesla are currently running a referral programme and offering buyers using the referral code a credit towards their new vehicle.</p>

<p>If you want to</p>]]></description><link>http://blog.irrelon.com/tesla-referral-discount/</link><guid isPermaLink="false">4034c7bc-54bd-4955-914c-2e9b81436950</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Thu, 02 Jun 2016 09:49:58 GMT</pubDate><content:encoded><![CDATA[<p><img src="http://www.irrelon.com/images/modelS.jpg" alt="Tesla Model S"></p>

<p>If you happen to be considering purchasing a Tesla (the world's most awesome car) you now have an opportunity to get a £750 / $1,000 discount. Tesla are currently running a referral programme and offering buyers using the referral code a credit towards their new vehicle.</p>

<p>If you want to purchase a Tesla, you can use my referral code here: <a href="http://ts.la/rob4462">Tesla Motors Referral</a></p>]]></content:encoded></item><item><title><![CDATA[Greenkeeper Evaluation]]></title><description><![CDATA[<p>Just a quick heads-up, we are currently evaluating GreenKeeper, a new service that automatically updates your NPM dependencies and pushes the updates to a new branch, runs your unit tests and tells you if the tests passed or failed.</p>

<p>This services allows us to automatically stay up to date with</p>]]></description><link>http://blog.irrelon.com/greenkeeper-evaluation/</link><guid isPermaLink="false">9c60496b-1123-4ce8-a838-46d8fa1a9ea8</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Thu, 02 Jun 2016 09:43:35 GMT</pubDate><content:encoded><![CDATA[<p>Just a quick heads-up, we are currently evaluating GreenKeeper, a new service that automatically updates your NPM dependencies and pushes the updates to a new branch, runs your unit tests and tells you if the tests passed or failed.</p>

<p>This services allows us to automatically stay up to date with changes to dependencies without manually running through new versions ever time a dependency changes.</p>

<p><a href="https://greenkeeper.io/">You can check out GreenKeeper here</a>.</p>]]></content:encoded></item><item><title><![CDATA[ForerunnerDB Reaches 42,000 Downloads a Month!]]></title><description><![CDATA[<blockquote>
  <p>UPDATE! It's now at 63,000 a month! :)</p>
  
  <p><img src="http://www.irrelon.com/images/forerunnerDBDownloads06-06-2016.png" alt="ForerunnerDB Downloads from NPM, 6th June 2016" title=""></p>
</blockquote>

<p>ForerunnerDB's first commit was on 7th February 2014. Two years on and it is now a highly popular JavaScript database solution receiving over 42,000 downloads a month on NPM alone!</p>

<p><img src="http://www.irrelon.com/images/forerunnerDBDownloads.png" alt="ForerunnerDB Downloads from NPM, 2nd June 2016"></p>

<p>This is a landmark in our quest to create the best</p>]]></description><link>http://blog.irrelon.com/forerunnerdb-reaches-42000-downloads-a-month/</link><guid isPermaLink="false">32d809b1-04e9-4bfa-ab4c-1e36b52ce155</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Thu, 02 Jun 2016 09:35:46 GMT</pubDate><content:encoded><![CDATA[<blockquote>
  <p>UPDATE! It's now at 63,000 a month! :)</p>
  
  <p><img src="http://www.irrelon.com/images/forerunnerDBDownloads06-06-2016.png" alt="ForerunnerDB Downloads from NPM, 6th June 2016" title=""></p>
</blockquote>

<p>ForerunnerDB's first commit was on 7th February 2014. Two years on and it is now a highly popular JavaScript database solution receiving over 42,000 downloads a month on NPM alone!</p>

<p><img src="http://www.irrelon.com/images/forerunnerDBDownloads.png" alt="ForerunnerDB Downloads from NPM, 2nd June 2016"></p>

<p>This is a landmark in our quest to create the best browser-based JSON database system available. Thank you to all of you who have downloaded and used ForerunnerDB, we hope it has made your life easier and your projects more enjoyable to code!</p>]]></content:encoded></item><item><title><![CDATA[ForerunnerDB Geospatial Queries]]></title><description><![CDATA[<p><img src="http://www.irrelon.com/images/geospatial.jpg" alt="Geospatial Indexes"></p>

<p>Geospatial queries allow you to find documents that are tagged with longitude / latitude coordinates by distance from a centre point.</p>

<p>ForerunnerDB will return results ordered by distance from the centre point, closest first. Geospatial indexing in ForerunnerDB takes the longitude and latitude coordinates in a document and converts them to</p>]]></description><link>http://blog.irrelon.com/forerunnerdb-geospatial-queries/</link><guid isPermaLink="false">4567c351-5704-446d-86ba-292f5c278358</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Thu, 02 Jun 2016 09:25:58 GMT</pubDate><content:encoded><![CDATA[<p><img src="http://www.irrelon.com/images/geospatial.jpg" alt="Geospatial Indexes"></p>

<p>Geospatial queries allow you to find documents that are tagged with longitude / latitude coordinates by distance from a centre point.</p>

<p>ForerunnerDB will return results ordered by distance from the centre point, closest first. Geospatial indexing in ForerunnerDB takes the longitude and latitude coordinates in a document and converts them to an internal geohash. Geohashes are then used inside a b-tree to query nearby hashes in a performant manor.</p>

<p>Geospatial queries will only work on collections with a geospatial (2d) index.</p>

<p>You can read the ForerunnerDB manual to find out more about geo-spatial queries here: <a href="https://github.com/Irrelon/ForerunnerDB/tree/master#geospatial-2d-queries">https://github.com/Irrelon/ForerunnerDB/tree/master#geospatial-2d-queries</a></p>]]></content:encoded></item><item><title><![CDATA[ZWay UZB Installation on Debian x64 Hardware]]></title><description><![CDATA[<p>I have run my own zwave server for some time using Node.js to communicate directly with a controller dongle. Recently I purchased a ZWay UZB stick so that I could focus on writing applications instead of driver layer software for zwave.</p>

<p>I had ZWay working fine on an older</p>]]></description><link>http://blog.irrelon.com/zway-with-uzb-stick-debian-ubuntu-x64/</link><guid isPermaLink="false">b7490d15-5a81-4a7c-a342-dd98574c3567</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Sun, 29 Nov 2015 12:05:31 GMT</pubDate><content:encoded><![CDATA[<p>I have run my own zwave server for some time using Node.js to communicate directly with a controller dongle. Recently I purchased a ZWay UZB stick so that I could focus on writing applications instead of driver layer software for zwave.</p>

<p>I had ZWay working fine on an older version of Ubuntu of but I wanted to install a supported version (Ubuntu 14.04) but after installing a clean Ubuntu 14.04 then running the install for ZWay I found it was horribly broken.</p>

<p>There appears to be little or no information about getting ZWay installed on Ubuntu or Debian other than a little snippet on the ZWay installation page:</p>

<blockquote>
  <p>Z-Way for RaZberry is supported on Raspbian distribution for Raspberry Pi computer. Although it can be launched on other Raspberry Pi distributions too.</p>
</blockquote>

<p>It turns out what this means is you need to manually download a debian version and then manually set it up.</p>

<p>So:</p>

<p>Install some dependencies first:</p>

<pre><code>apt-get -y update
sudo apt-get -qy install libxml2 libarchive-dev curl
sudo apt-get -qy install sharutils tzdata gawk
sudo apt-get -qy install libavahi-compat-libdnssd-dev
</code></pre>

<p>Link a dependency with newer name:</p>

<pre><code>sudo ln -s /usr/lib/x86_64-linux-gnu/libarchive.so.13 /usr/lib/x86_64-linux-gnu/libarchive.so.12
</code></pre>

<p>Go to <a href="http://razberry.z-wave.me/z-way-server">http://razberry.z-wave.me/z-way-server</a> and download the latest version 2.0.1 to your server, I used <a href="http://razberry.z-wave.me/z-way-server/z-way-server-Ubuntu-v2.0.1.tgz">http://razberry.z-wave.me/z-way-server/z-way-server-Ubuntu-v2.0.1.tgz</a></p>

<blockquote>
  <p>I tried ALL other versions including later ones and NONE worked. Only 2.0.1 would work!</p>
  
  <p><strong>UPDATE</strong> I was able to get the newer versions 2.1.1 and 2.1.2-rc17 working but I had to contact zwaveeurope.com (the retailer of my UZB stick) and request a new license key. After starting 2.1.1 and entering the new key into zway, I was able to get it working. Version 2.1.2-rc17 also worked after the new key was entered.</p>
</blockquote>

<p>Get the file:</p>

<pre><code>wget http://razberry.z-wave.me/z-way-server/z-way-server-Ubuntu-v2.0.1.tgz
</code></pre>

<p>Untar the zip file:</p>

<pre><code>sudo tar -zxf z-way-server-Ubuntu-v2.0.1.tgz -C /opt/
</code></pre>

<p>Create a service installer file:</p>

<pre><code>nano install-service.sh
</code></pre>

<p>Paste the below text into it:</p>

<pre><code>#!/usr/bin/env bash

# Create Z-Way startup script
echo "Creating Z-Way startup script"  
echo '#! /bin/sh  
### BEGIN INIT INFO
# Provides:          z-way-server
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Z-Way service
# Description:       Start Z-Way server for to allow comms with Z-Wave devices
### END INIT INFO

# Description: Z-Way server
# Author: Rob Evans &lt;rob@irrelon.com&gt;

PATH=/bin:/usr/bin:/sbin:/usr/sbin  
NAME=z-way-server  
DAEMON_PATH=/opt/z-way-server  
PIDFILE=/var/run/$NAME.pid

# adding z-way libs to library path
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/z-way-server/libs

case "$1" in  
  start)
    echo -n "Starting z-way-server: "
    start-stop-daemon --start  --pidfile $PIDFILE --make-pidfile  --background --no-close --chdir $DAEMON_PATH --exec $NAME &gt; /dev/null 2&gt;&amp;1
    echo "done."
    ;;
  stop)
    echo -n "Stopping z-way-server: "
    start-stop-daemon --stop --quiet --pidfile $PIDFILE
    rm $PIDFILE
    echo "done."
    ;;
  restart)
    echo "Restarting z-way-server: "
    sh $0 stop
    sleep 10
    sh $0 start
    ;;
  save)
    echo "Saving z-way-server configuration"
    PID=`sed s/[^0-9]//g $PIDFILE`
    /bin/kill -10 $PID
    ;;
  *)
    echo "Usage: /etc/init.d/z-way-server {start|stop|restart|save}"
    exit 1
    ;;
esac  
exit 0' &gt; /etc/init.d/z-way-server  
chmod +x /etc/init.d/z-way-server

# Add z-way-server.log to logrotate
echo '/var/log/z-way-server.log {  
        daily
        size=10M
        rotate 4
        compress
        nodelaycompress
        missingok
        notifempty
        postrotate
            /usr/bin/killall -HUP z-way-server 2&gt;/dev/null || true
        endscript
}' &gt; /etc/logrotate.d/z-way-server

# Add Z-Way to autostart
echo "Adding z-way-server to autostart"  
update-rc.d z-way-server defaults  
</code></pre>

<p>Now run the service installer:</p>

<pre><code>sudo bash install-service.sh
</code></pre>

<p>To check for any issues and see debug output you should manually launch z-way-server and look at the debug log on screen for any issues. To do that you can run (in the z-way-server folder):</p>

<pre><code>cd /opt/z-way-server
LD_LIBRARY_PATH=libs ./z-way-server
</code></pre>

<p>Once you are satisfied everything is working by navigating to your server's IP under port 8083, you can start your z-way-server service via:</p>

<pre><code>sudo service z-way-server start
</code></pre>

<p>Enjoy!</p>]]></content:encoded></item><item><title><![CDATA[SnagBook - Snagging Made Easy]]></title><description><![CDATA[<p>Have you recently purchased a new-build home only to find like many others that it also comes with a bunch of <strong>defects</strong>, overlooked issues, <strong>rushed or sloppy work</strong> or even worse - structural build errors?</p>

<p>If you're anything like me, <strong>keeping track of every little snag with your new home</strong></p>]]></description><link>http://blog.irrelon.com/snagthis-snagging-made-easy/</link><guid isPermaLink="false">7a715265-8530-43b0-a9a2-1af88c39af9f</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Fri, 29 May 2015 12:45:13 GMT</pubDate><content:encoded><![CDATA[<p>Have you recently purchased a new-build home only to find like many others that it also comes with a bunch of <strong>defects</strong>, overlooked issues, <strong>rushed or sloppy work</strong> or even worse - structural build errors?</p>

<p>If you're anything like me, <strong>keeping track of every little snag with your new home</strong> can become a difficult and time consuming process. Sometimes you'll walk into a room and see a snag that you just keep forgetting to report to your developer but don't have time to call and log.</p>

<p>Once your developer does start to fix your snags you can run into other issues like remembering the exact conversation and what work was agreed.</p>

<p>Wouldn't it be better to have all this <strong>logged and tracked automatically</strong>, with <strong>a history log for each snag</strong> issue easily brought up when it was needed?</p>

<h3 id="snagbookisyournewfriend">SnagBook is Your New Friend</h3>

<p>With <a href="http://www.snagbook.co.uk">SnagBook</a>, keeping track of your new home snagging issues is easy. Logging new snags is a simple process, and viewing a snag's history is effortless.</p>

<p>SnagBook is <strong>FREE</strong> to use and there are <strong>no charges or subscription fees</strong> EVER.</p>

<p>Furthermore, each snag can be automatically reported to your developer meaning no more annoying phone calls to describe your problem. When your developer is ready to fix your snag you get sent a notification and details of the fix, along with a schedule of when it will be done.</p>

<p>Logging, communicating and getting a response to your snags is now a simple affair. Check it out!</p>

<p><a href="http://www.snagbook.co.uk">http://www.snagbook.co.uk</a></p>]]></content:encoded></item><item><title><![CDATA[NPM Publish Development Branch / Beta Code]]></title><description><![CDATA[Publish your npm module under a beta tag so it won't be installed by default using the npm install command.]]></description><link>http://blog.irrelon.com/npm-publish-development-branch-beta-code/</link><guid isPermaLink="false">0330ff32-693f-4f62-aaad-aaf74dcb5e30</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Sat, 18 Apr 2015 11:36:01 GMT</pubDate><content:encoded><![CDATA[<p>If you want to publish a version of your module under a tag other than latest (which is what is used by default), then simply include the --tag option when publishing with the name of the tag you wish to use.</p>

<p>For example if you want to publish with the tag "beta" you would type:</p>

<blockquote>
  <p>npm publish --tag beta</p>
</blockquote>

<p>The version you have just published will be registered under the beta tag rather than the latest tag, and will not be installed when someone attempts to install your package with the npm install <packagename> command.</packagename></p>

<p>You can install different tagged versions using the npm install --tag <tagname> command. For instance to install ForerunnerDB's dev version:</tagname></p>

<blockquote>
  <p>npm install forerunnerdb --tag dev</p>
</blockquote>]]></content:encoded></item><item><title><![CDATA[Irrelon Software's Own Planet & Space Station!]]></title><description><![CDATA[Come visit us in ED at our very own space station!]]></description><link>http://blog.irrelon.com/irrelon-softwares-own-planet-space-station/</link><guid isPermaLink="false">bdf5cfe6-376e-44d4-b36e-ea55bfa4a881</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Tue, 16 Dec 2014 12:00:00 GMT</pubDate><media:content url="http://blog.irrelon.com/content/images/2016/08/Elite-Dangerous-Completionists-Can-Compete-for-10-000-12-000-15-000-in-Prizes-467753-2.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://blog.irrelon.com/content/images/2016/08/Elite-Dangerous-Completionists-Can-Compete-for-10-000-12-000-15-000-in-Prizes-467753-2.jpg" alt="Irrelon Software's Own Planet & Space Station!"><p>Just a quick heads-up that Irrelon has its own starbase in Elite Dangerous. For any fans of the game out there, we helped kickstart Elite Dangerous and one of the benefits was the ability to name our own planet and space station. If you're out and about in deep space, come visit us at Irrelon Orbital: <a href="http://ed-td.space/en/11/Station/idSys/3092/nSys/CD-77+45/idSta/17520/nSta/Irrelon+Orbital">http://ed-td.space/en/11/Station/idSys/3092/nSys/CD-77+45/idSta/17520/nSta/Irrelon+Orbital</a></p>]]></content:encoded></item><item><title><![CDATA[SyncScript - Non-Blocking Synchronous JS]]></title><description><![CDATA[<p>Explore SyncScript from the GitHub repository here: <a href="https://github.com/irrelon/SyncScript">https://github.com/irrelon/SyncScript</a></p>

<h3 id="whatissynchronouscode">What is Synchronous Code?</h3>

<p>When coding in JavaScript it is very common to see code with callbacks. This allows a process to go off, do something lengthy or time consuming and then callback when complete.</p>

<pre><code>doSomethingLengthy(function (a)</code></pre>]]></description><link>http://blog.irrelon.com/syncscript-non-blocking-synchronous-js/</link><guid isPermaLink="false">12d00652-639a-4d7b-8666-2bbe1ea77991</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Wed, 26 Nov 2014 11:56:29 GMT</pubDate><content:encoded><![CDATA[<p>Explore SyncScript from the GitHub repository here: <a href="https://github.com/irrelon/SyncScript">https://github.com/irrelon/SyncScript</a></p>

<h3 id="whatissynchronouscode">What is Synchronous Code?</h3>

<p>When coding in JavaScript it is very common to see code with callbacks. This allows a process to go off, do something lengthy or time consuming and then callback when complete.</p>

<pre><code>doSomethingLengthy(function (a) {
    console.log(a);
});
</code></pre>

<p>Synchronous code by comparison flows naturally from one line to the next without any callbacks. It looks like this:</p>

<pre><code>var a = doSomethingLengthy();
console.log(a);
</code></pre>

<p>The sync version of the code has a problem though... it will block execution until doSomethingLengthy() is complete. In a browser this will mean the UI locks up and the user is left with a poor experience.</p>

<p>Callback-based code does not block execution but your code is less readable by another human. If your app is slightly more complex you can have callbacks inside callbacks inside more callbacks.</p>

<h3 id="syncscriptsolvesthis">SyncScript Solves This</h3>

<p>SyncScript is JavaScript but adds another keyword that allows you to write synchronous code that executes like callback-based code. SyncScript works in all JavaScript compatible browsers and environments and is 100% JavaScript compatible, requires no extra libraries or downloads and does not need a separate runtime.</p>

<p>All libraries, all plugins and all existing code works without issue with SyncScript.</p>

<p>SyncScript code looks like this:</p>

<pre><code>var a = sync(doSomethingLengthy());
console.log(a);
</code></pre>

<h3 id="passingmultiplearguments">Passing Multiple Arguments</h3>

<p>Let's say we modify doSomethingLengthy() to require some arguments... now the defintion of doSomethingLengthy() is:</p>

<pre><code>var doSomethingLengthy = function (url, flags, callback) {
    // Do some lengthy stuff

    // Lengthy stuff done, callback
    callback('moo');
};
</code></pre>

<p>SyncScript will work with this too:</p>

<pre><code>var a = sync(doSomethingLengthy(
    'http://www.irrelon.com', { flag1: true }
));
</code></pre>

<p>When this call is done the value passed in the callback is assigned to 'a' so it now equals 'moo'.</p>

<h3 id="callbackwithmultiplevalues">Callback With Multiple Values</h3>

<p>The above example is great if you only callback with a single value but what about passing back multiple values? That's pretty simple too, just declare multiple variables in the order they are passed back, before the call to sync(). Here is a more likely example:</p>

<pre><code>var err, data = sync(doSomethingLengthy(
    'http://www.irrelon.com', { flag1: true }
));
</code></pre>

<h3 id="settingcallbackscope">Setting Callback Scope</h3>

<p>You can section areas of code into distinct async calls that will execute in parallel by wrapping them in curly braces. Take the following code for example. The second call to addSync waits for the first to finish:</p>

<pre><code>var err, myVal = sync(addAsync(1, 2, 3, 4));  
console.log(myVal);

var err, myVal = sync(addAsync(1, 2, 3, 4));  
console.log(myVal);  
</code></pre>

<p>What if you want both async calls to execute at the same time? You can achieve this by wrapping each call <br>
and it's dependant code in braces:</p>

<pre><code>{
    var err, myVal = sync(addAsync(1, 2, 3, 4));
    console.log(myVal);
}

{
    var err, myVal = sync(addAsync(1, 2, 3, 4));
    console.log(myVal);
}
</code></pre>

<p>Now both calls will execute and return in whichever order they complete in.</p>

<h3 id="howsyncscriptworks">How SyncScript Works</h3>

<p>SyncScript transpiles to an AST after which the tree is analysed, sync calls are identified and then the AST is modified to produce callback-based code where the sync calls are. After modification of the AST it is taken and re-compiled back into JavaScript.</p>

<h3 id="furtherreading">Further Reading</h3>

<p>You can read more about SyncScript and the future development roadmap, download and see usage instructions at <a href="https://github.com/irrelon/SyncScript">https://github.com/irrelon/SyncScript</a></p>]]></content:encoded></item><item><title><![CDATA[Reachability in Apple iOS 7 & 8]]></title><description><![CDATA[<p>Detecting Online / Offline Status</p>

<p>Almost every app you develop for Apple's iOS will need a way to detect if it has an internet connection or not. Using the Reachability class you can ask to be informed when the status of the internet connection changes, as well as what the status</p>]]></description><link>http://blog.irrelon.com/reachability-in-apple-ios/</link><guid isPermaLink="false">61c8fd4b-215f-4eb8-a789-dbae21e702c1</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Thu, 30 Oct 2014 12:54:30 GMT</pubDate><content:encoded><![CDATA[<p>Detecting Online / Offline Status</p>

<p>Almost every app you develop for Apple's iOS will need a way to detect if it has an internet connection or not. Using the Reachability class you can ask to be informed when the status of the internet connection changes, as well as what the status is when your app starts up.</p>

<p>In this tutorial I will explain how you can create a reachability system that allows you to check for internet connectivity at any point in your application's life-cycle.</p>

<h3 id="thecode">The Code</h3>

<h5 id="step1includereachablity">Step 1: Include Reachablity</h5>

<blockquote>
  <p>Reachability.h</p>
</blockquote>

<pre><code>/*
 Copyright (c) 2011, Tony Million.
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#import &lt;Foundation/Foundation.h&gt;
#import &lt;SystemConfiguration/SystemConfiguration.h&gt;

#import &lt;sys/socket.h&gt;
#import &lt;netinet/in.h&gt;
#import &lt;netinet6/in6.h&gt;
#import &lt;arpa/inet.h&gt;
#import &lt;ifaddrs.h&gt;
#import &lt;netdb.h&gt;

/**
 * Does ARC support GCD objects?
 * It does if the minimum deployment target is iOS 6+ or Mac OS X 8+
 *
 * @see http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
 **/
#if OS_OBJECT_USE_OBJC
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
#else
#define NEEDS_DISPATCH_RETAIN_RELEASE 1
#endif

/**
 * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X.
 *
 * @see http://nshipster.com/ns_enum-ns_options/
 **/
#ifndef NS_ENUM
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#endif

extern NSString *const kReachabilityChangedNotification;

typedef NS_ENUM(NSInteger, NetworkStatus) {  
    // Apple NetworkStatus Compatible Names.
    NotReachable = 0,
    ReachableViaWiFi = 2,
    ReachableViaWWAN = 1
};

@class Reachability;

typedef void (^NetworkReachable)(Reachability * reachability);  
typedef void (^NetworkUnreachable)(Reachability * reachability);

@interface Reachability : NSObject

@property (nonatomic, copy) NetworkReachable    reachableBlock;
@property (nonatomic, copy) NetworkUnreachable  unreachableBlock;


@property (nonatomic, assign) BOOL reachableOnWWAN;

+(Reachability*)reachabilityWithHostname:(NSString*)hostname;
// This is identical to the function above, but is here to maintain
//compatibility with Apples original code. (see .m)
+(Reachability*)reachabilityWithHostName:(NSString*)hostname;
+(Reachability*)reachabilityForInternetConnection;
+(Reachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress;
+(Reachability*)reachabilityForLocalWiFi;

-(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;

-(BOOL)startNotifier;
-(void)stopNotifier;

-(BOOL)isReachable;
-(BOOL)isReachableViaWWAN;
-(BOOL)isReachableViaWiFi;

// WWAN may be available, but not active until a connection has been established.
// WiFi may require a connection for VPN on Demand.
-(BOOL)isConnectionRequired; // Identical DDG variant.
-(BOOL)connectionRequired; // Apple's routine.
                           // Dynamic, on demand connection?
-(BOOL)isConnectionOnDemand;
// Is user intervention required?
-(BOOL)isInterventionRequired;

-(NetworkStatus)currentReachabilityStatus;
-(SCNetworkReachabilityFlags)reachabilityFlags;
-(NSString*)currentReachabilityString;
-(NSString*)currentReachabilityFlags;

@end
</code></pre>

<blockquote>
  <p>Reachability.m</p>
</blockquote>

<pre><code>/*
 Copyright (c) 2011, Tony Million.
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

#import "Reachability.h"


NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification";

@interface Reachability ()

@property (nonatomic, assign) SCNetworkReachabilityRef  reachabilityRef;


#if NEEDS_DISPATCH_RETAIN_RELEASE
@property (nonatomic, assign) dispatch_queue_t          reachabilitySerialQueue;
#else
@property (nonatomic, strong) dispatch_queue_t          reachabilitySerialQueue;
#endif


@property (nonatomic, strong) id reachabilityObject;

-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags;
-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags;

@end

static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags)  
{
    return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c",
#if    TARGET_OS_IPHONE
            (flags &amp; kSCNetworkReachabilityFlagsIsWWAN)               ? 'W' : '-',
#else
            'X',
#endif
            (flags &amp; kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',
            (flags &amp; kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',
            (flags &amp; kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',
            (flags &amp; kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
            (flags &amp; kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',
            (flags &amp; kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',
            (flags &amp; kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',
            (flags &amp; kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-'];
}

// Start listening for reachability notifications on the current run loop
static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)  
{
#pragma unused (target)
#if __has_feature(objc_arc)
    Reachability *reachability = ((__bridge Reachability*)info);
#else
    Reachability *reachability = ((Reachability*)info);
#endif

    // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool,
    // but what the heck eh?
    @autoreleasepool
    {
        [reachability reachabilityChanged:flags];
    }
}


@implementation Reachability

@synthesize reachabilityRef;
@synthesize reachabilitySerialQueue;

@synthesize reachableOnWWAN;

@synthesize reachableBlock;
@synthesize unreachableBlock;

@synthesize reachabilityObject;

#pragma mark - Class Constructor Methods

+(Reachability*)reachabilityWithHostName:(NSString*)hostname
{
    return [Reachability reachabilityWithHostname:hostname];
}

+(Reachability*)reachabilityWithHostname:(NSString*)hostname
{
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
    if (ref)
    {
        id reachability = [[self alloc] initWithReachabilityRef:ref];

#if __has_feature(objc_arc)
        return reachability;
#else
        return [reachability autorelease];
#endif

    }

    return nil;
}

+(Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
{
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
    if (ref)
    {
        id reachability = [[self alloc] initWithReachabilityRef:ref];

#if __has_feature(objc_arc)
        return reachability;
#else
        return [reachability autorelease];
#endif
    }

    return nil;
}

+(Reachability *)reachabilityForInternetConnection
{
    struct sockaddr_in zeroAddress;
    bzero(&amp;zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    return [self reachabilityWithAddress:&amp;zeroAddress];
}

+(Reachability*)reachabilityForLocalWiFi
{
    struct sockaddr_in localWifiAddress;
    bzero(&amp;localWifiAddress, sizeof(localWifiAddress));
    localWifiAddress.sin_len            = sizeof(localWifiAddress);
    localWifiAddress.sin_family         = AF_INET;
    // IN_LINKLOCALNETNUM is defined in &lt;netinet/in.h&gt; as 169.254.0.0
    localWifiAddress.sin_addr.s_addr    = htonl(IN_LINKLOCALNETNUM);

    return [self reachabilityWithAddress:&amp;localWifiAddress];
}


// Initialization methods

-(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref
{
    self = [super init];
    if (self != nil)
    {
        self.reachableOnWWAN = YES;
        self.reachabilityRef = ref;
    }

    return self;
}

-(void)dealloc
{
    [self stopNotifier];

    if(self.reachabilityRef)
    {
        CFRelease(self.reachabilityRef);
        self.reachabilityRef = nil;
    }

    self.reachableBlock     = nil;
    self.unreachableBlock   = nil;

#if !(__has_feature(objc_arc))
    [super dealloc];
#endif


}

#pragma mark - Notifier Methods

// Notifier
// NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD
// - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS.
//   INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want)

-(BOOL)startNotifier
{
    SCNetworkReachabilityContext    context = { 0, NULL, NULL, NULL, NULL };

    // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves
    // woah
    self.reachabilityObject = self;



    // First, we need to create a serial queue.
    // We allocate this once for the lifetime of the notifier.
    self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL);
    if(self.reachabilitySerialQueue == nil)
    {
        return NO;
    }

#if __has_feature(objc_arc)
    context.info = (__bridge void *)self;
#else
    context.info = (void *)self;
#endif

    if (!SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &amp;context))
    {
#ifdef DEBUG
        NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));
#endif

        // Clear out the dispatch queue
        if(self.reachabilitySerialQueue)
        {
#if NEEDS_DISPATCH_RETAIN_RELEASE
            dispatch_release(self.reachabilitySerialQueue);
#endif
            self.reachabilitySerialQueue = nil;
        }

        self.reachabilityObject = nil;

        return NO;
    }

    // Set it as our reachability queue, which will retain the queue
    if(!SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
    {
#ifdef DEBUG
        NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
#endif

        // UH OH - FAILURE!

        // First stop, any callbacks!
        SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);

        // Then clear out the dispatch queue.
        if(self.reachabilitySerialQueue)
        {
#if NEEDS_DISPATCH_RETAIN_RELEASE
            dispatch_release(self.reachabilitySerialQueue);
#endif
            self.reachabilitySerialQueue = nil;
        }

        self.reachabilityObject = nil;

        return NO;
    }

    return YES;
}

-(void)stopNotifier
{
    // First stop, any callbacks!
    SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);

    // Unregister target from the GCD serial dispatch queue.
    SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL);

    if(self.reachabilitySerialQueue)
    {
#if NEEDS_DISPATCH_RETAIN_RELEASE
        dispatch_release(self.reachabilitySerialQueue);
#endif
        self.reachabilitySerialQueue = nil;
    }

    self.reachabilityObject = nil;
}

#pragma mark - reachability tests

// This is for the case where you flick the airplane mode;
// you end up getting something like this:
//Reachability: WR ct-----
//Reachability: -- -------
//Reachability: WR ct-----
//Reachability: -- -------
// We treat this as 4 UNREACHABLE triggers - really apple should do better than this

#define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)

-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags
{
    BOOL connectionUP = YES;

    if(!(flags &amp; kSCNetworkReachabilityFlagsReachable))
        connectionUP = NO;

    if( (flags &amp; testcase) == testcase )
        connectionUP = NO;

#if    TARGET_OS_IPHONE
    if(flags &amp; kSCNetworkReachabilityFlagsIsWWAN)
    {
        // We're on 3G.
        if(!self.reachableOnWWAN)
        {
            // We don't want to connect when on 3G.
            connectionUP = NO;
        }
    }
#endif

    return connectionUP;
}

-(BOOL)isReachable
{
    SCNetworkReachabilityFlags flags;

    if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &amp;flags))
        return NO;

    return [self isReachableWithFlags:flags];
}

-(BOOL)isReachableViaWWAN
{
#if    TARGET_OS_IPHONE

    SCNetworkReachabilityFlags flags = 0;

    if(SCNetworkReachabilityGetFlags(reachabilityRef, &amp;flags))
    {
        // Check we're REACHABLE
        if(flags &amp; kSCNetworkReachabilityFlagsReachable)
        {
            // Now, check we're on WWAN
            if(flags &amp; kSCNetworkReachabilityFlagsIsWWAN)
            {
                return YES;
            }
        }
    }
#endif

    return NO;
}

-(BOOL)isReachableViaWiFi
{
    SCNetworkReachabilityFlags flags = 0;

    if(SCNetworkReachabilityGetFlags(reachabilityRef, &amp;flags))
    {
        // Check we're reachable
        if((flags &amp; kSCNetworkReachabilityFlagsReachable))
        {
#if    TARGET_OS_IPHONE
            // Check we're NOT on WWAN
            if((flags &amp; kSCNetworkReachabilityFlagsIsWWAN))
            {
                return NO;
            }
#endif
            return YES;
        }
    }

    return NO;
}


// WWAN may be available, but not active until a connection has been established.
// WiFi may require a connection for VPN on Demand.
-(BOOL)isConnectionRequired
{
    return [self connectionRequired];
}

-(BOOL)connectionRequired
{
    SCNetworkReachabilityFlags flags;

    if(SCNetworkReachabilityGetFlags(reachabilityRef, &amp;flags))
    {
        return (flags &amp; kSCNetworkReachabilityFlagsConnectionRequired);
    }

    return NO;
}

// Dynamic, on demand connection?
-(BOOL)isConnectionOnDemand
{
    SCNetworkReachabilityFlags flags;

    if (SCNetworkReachabilityGetFlags(reachabilityRef, &amp;flags))
    {
        return ((flags &amp; kSCNetworkReachabilityFlagsConnectionRequired) &amp;&amp;
                (flags &amp; (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand)));
    }

    return NO;
}

// Is user intervention required?
-(BOOL)isInterventionRequired
{
    SCNetworkReachabilityFlags flags;

    if (SCNetworkReachabilityGetFlags(reachabilityRef, &amp;flags))
    {
        return ((flags &amp; kSCNetworkReachabilityFlagsConnectionRequired) &amp;&amp;
                (flags &amp; kSCNetworkReachabilityFlagsInterventionRequired));
    }

    return NO;
}


#pragma mark - reachability status stuff

-(NetworkStatus)currentReachabilityStatus
{
    if([self isReachable])
    {
        if([self isReachableViaWiFi])
            return ReachableViaWiFi;

#if    TARGET_OS_IPHONE
        return ReachableViaWWAN;
#endif
    }

    return NotReachable;
}

-(SCNetworkReachabilityFlags)reachabilityFlags
{
    SCNetworkReachabilityFlags flags = 0;

    if(SCNetworkReachabilityGetFlags(reachabilityRef, &amp;flags))
    {
        return flags;
    }

    return 0;
}

-(NSString*)currentReachabilityString
{
    NetworkStatus temp = [self currentReachabilityStatus];

    if(temp == reachableOnWWAN)
    {
        // Updated for the fact that we have CDMA phones now!
        return NSLocalizedString(@"Cellular", @"");
    }
    if (temp == ReachableViaWiFi)
    {
        return NSLocalizedString(@"WiFi", @"");
    }

    return NSLocalizedString(@"No Connection", @"");
}

-(NSString*)currentReachabilityFlags
{
    return reachabilityFlags([self reachabilityFlags]);
}

#pragma mark - Callback function calls this method

-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags
{
    if([self isReachableWithFlags:flags])
    {
        if(self.reachableBlock)
        {
            self.reachableBlock(self);
        }
    }
    else
    {
        if(self.unreachableBlock)
        {
            self.unreachableBlock(self);
        }
    }

    // this makes sure the change notification happens on the MAIN THREAD
    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification
                                                            object:self];
    });
}

#pragma mark - Debug Description

- (NSString *) description
{
    NSString *description = [NSString stringWithFormat:@"&lt;%@: %#x&gt;",
                             NSStringFromClass([self class]), (unsigned int) self];
    return description;
}

@end
</code></pre>

<h5 id="step2includeconnectionstatus">Step 2: Include ConnectionStatus</h5>

<blockquote>
  <p>ConnectionStatus.h</p>
</blockquote>

<pre><code>//
//  ConnectionStatus.h
//  Irrelon Software Limited
//
//  Created by Rob Evans on 02/03/2014.
//  Copyright (c) 2014 Irrelon Software Limited. All rights reserved.
//

#import &lt;Foundation/Foundation.h&gt;

@interface ConnectionStatus : NSObject

@property BOOL _connectionStatus;

+ (id)sharedInstance;
- (BOOL)isConnected;
- (void)setConnected:(BOOL)state;

@end
</code></pre>

<blockquote>
  <p>ConnectionStatus.m</p>
</blockquote>

<pre><code>//
//  ConnectionStatus.m
//  Irrelon Software Limited
//
//  Created by Rob Evans on 02/03/2014.
//  Copyright (c) 2014 Irrelon Software Limited. All rights reserved.
//

#import "ConnectionStatus.h"

@implementation ConnectionStatus

+ (id)sharedInstance {
    // structure used to test whether the block has completed or not
    static dispatch_once_t p = 0;

    // initialize sharedObject as nil (first call only)
    __strong static id _sharedObject = nil;

    // executes a block object once and only once for the lifetime of an application
    dispatch_once(&amp;p, ^{
        _sharedObject = [[self alloc] init];
    });

    // returns the same object each time
    return _sharedObject;
}

- (id)init {
    self = [super init];

    if (self) {
        self._connectionStatus = false;
    }

    return self;
}

- (BOOL)isConnected {
    return self._connectionStatus;
}

- (void)setConnected:(BOOL)state {
    self._connectionStatus = state;
}

@end
</code></pre>

<h5 id="step2updateyourappdelegateh">Step 2: Update Your App Delegate .h</h5>

<p>1: Add the Reachability.h and ConnectionState.h to your imports in your app delegate's .h file <br>
2: Add a property "hostReachability" to the app delegate's properties <br>
3: Add the "reachabilityChanged" method definition</p>

<pre><code>#import &lt;UIKit/UIKit.h&gt;
#import "Reachability.h"
#import "ConnectionState.h"

@interface AppDelegate : UIResponder &lt;UIApplicationDelegate&gt;

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) Reachability *hostReachability;

- (void)reachabilityChanged:(NSNotification *)notification;

@end
</code></pre>

<h5 id="step3addcodetoappdelegatem">Step 3: Add Code to App Delegate .m</h5>

<p>Add the following code into the "applicationWillEnterForeground" method AND the "applicationDidBecomeActive" method:  </p>

<pre><code>[self startReachabilityCheck];
</code></pre>

<p>Then add the startReachabilityCheck method to the app delegate .m:</p>

<pre><code>- (void)startReachabilityCheck {
    // Check if we need to create a hostReachability instance
    if (self.hostReachability == nil) {
        // Create an instance of reachability
        self.hostReachability = [Reachability reachabilityForInternetConnection];

        // Listen for changes
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(reachabilityChanged:)
                                                     name:kReachabilityChangedNotification
                                                   object:nil];
    }

    // Start notifications
    [self.hostReachability startNotifier];

    // Set the current reachability
    [[ConnectionState sharedInstance] setConnected:[self.hostReachability isReachable]];
}
</code></pre>

<h3 id="usage">Usage</h3>

<p>Now that your app is set up to maintain a status of your internet connectivity you can check for a valid connection at any time in your app by <strong>importing "ConnectionStatus.h"</strong> and then using:</p>

<pre><code>BOOL status = [[ConnectionStatus sharedInstance] isConnected];  
</code></pre>]]></content:encoded></item><item><title><![CDATA[New ForerunnerDB Website Now Live]]></title><description><![CDATA[<p>Irrelon has been hard at work on ForerunnerDB and it's now ready for the world to play with. We've put together a lovely site with an interactive demo right there on the page so you can see just how cool a web-based database can be!</p>

<p>ForerunnerDB supports data-binding for realtime</p>]]></description><link>http://blog.irrelon.com/new-forerunnerdb-website-now-live/</link><guid isPermaLink="false">55cf7875-9020-4b8e-9751-4c120635bfcd</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Thu, 18 Sep 2014 22:09:46 GMT</pubDate><content:encoded><![CDATA[<p>Irrelon has been hard at work on ForerunnerDB and it's now ready for the world to play with. We've put together a lovely site with an interactive demo right there on the page so you can see just how cool a web-based database can be!</p>

<p>ForerunnerDB supports data-binding for realtime data-to-view linking, uses MongoDB's query language as its API and is the most advanced database available for your web app today.</p>

<p>Why not give it a spin over at <a href="http://www.forerunnerdb.com">http://www.forerunnerdb.com</a></p>

<p>Enjoy!</p>]]></content:encoded></item><item><title><![CDATA[Browserify vs Require.js]]></title><description><![CDATA[<p>In the world of web and server-side JavaScript development there is a need to be able to modularise your code and include it where it's needed without any fuss.</p>

<p>Up 'till now I've been using requirejs for modules but due to the pain it causes in development (and later deployment</p>]]></description><link>http://blog.irrelon.com/browserify-vs-require-js/</link><guid isPermaLink="false">a9644170-b7c9-4c4c-a4b4-d7921300b70d</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Fri, 12 Sep 2014 16:36:26 GMT</pubDate><content:encoded><![CDATA[<p>In the world of web and server-side JavaScript development there is a need to be able to modularise your code and include it where it's needed without any fuss.</p>

<p>Up 'till now I've been using requirejs for modules but due to the pain it causes in development (and later deployment building) I have been searching for an alternative.</p>

<h3 id="hellobrowserify">Hello Browserify</h3>

<p>Browserify uses Node.js to compile your JavaScript source modules into a single file that you can include in your web pages.</p>

<p>It allows you to write code and modularise it very easily:</p>

<pre><code>var MyModule = function () {  
    this._hello = true;
};

MyModule.prototype.hello = function (val) {  
    if (val !== undefined) {
        this._hello = val;
        return this;
    }

    return this._hello;
};

module.exports = MyModule;  
</code></pre>

<p>This module just defines a class we can instantiate that has a simple getter/setter method called "hello()".</p>

<p>In browserify to use this module you just require it:</p>

<pre><code>var MyModule = require('./myModule.js'),  
    myModule;

myModule = new MyModule();  
myModule.hello('moo');  
</code></pre>

<p>Simple and painless modules! I suggest you give browserify a good run, it will speed up your development and make your life a lot simpler!</p>]]></content:encoded></item><item><title><![CDATA[Require.js Made Easy]]></title><description><![CDATA[<p><a href="http://requirejs.org/">Require.js</a> is  a module loader / dependency handler that allows you to easily define code modules that will only execute once their dependencies exist.</p>

<p>The <em>require</em> site and documentation can be a tad confusing / overcomplex for a new user so I wanted to write a quick tutorial to make <em>require</em></p>]]></description><link>http://blog.irrelon.com/require-js-tutorial-made-easy/</link><guid isPermaLink="false">d9be0b74-f81b-4983-afcf-fab9d72cb8fc</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Wed, 26 Mar 2014 13:10:30 GMT</pubDate><content:encoded><![CDATA[<p><a href="http://requirejs.org/">Require.js</a> is  a module loader / dependency handler that allows you to easily define code modules that will only execute once their dependencies exist.</p>

<p>The <em>require</em> site and documentation can be a tad confusing / overcomplex for a new user so I wanted to write a quick tutorial to make <em>require</em> easy to understand.</p>

<h4 id="filestructure">File Structure</h4>

<p>Our example file structure is:</p>

<ul>
<li>index.html</li>
<li>/js
<ul><li>init.js</li>
<li>Car.js</li>
<li>Wheel.js</li></ul></li>
</ul>

<h4 id="includerequire">Include Require</h4>

<pre><code>&lt;script src="require.js" data-main="js/init.js"&gt;&lt;/script&gt;  
</code></pre>

<p>You'll notice the "data-main" attribute with the value "js/init.js". This data attribute tells <em>require</em> to load that script once <em>require</em> itself has loaded.</p>

<p>This allows you to have a single <code>&lt;script&gt;</code> tag that loads require.js and also specify a script to load to start your app, all in one tag.</p>

<h4 id="appentrypoint">App Entry Point</h4>

<p>We've specified to <em>require</em> that we want to load the init.js file on startup so here's the contents of that file:</p>

<pre><code>require(['Car'], function (Car) {  
    var car = new Car();
    car.drive();
});
</code></pre>

<p>You'll notice it calls "require()" instead of "define()"... that is because it doesn't provide any output, only describes what modules it needs.</p>

<p>Modules that don't <em>provide</em> anything can use require(). Modules that provide something use define();</p>

<h4 id="creatingamodule">Creating a Module</h4>

<p>Every file in your app is a module that can require other modules and provide data for other modules that require it.</p>

<p>Let's look at defining a module called Car:  </p>

<pre><code>// Define a module with it's dependencies (Wheel)
define(['Wheel'], function (Wheel) {  
    var Car = function () {
        this.wheel1 = new Wheel();
        this.wheel2 = new Wheel();
        this.wheel3 = new Wheel();
        this.wheel4 = new Wheel();
    };

    Car.prototype.drive = function () {
        console.log('Brrroooommm!');
    };

    return Car;
});
</code></pre>

<p>The define call takes an array of modules that this module depends on, in this case the Wheel module, and then passes each module's return value as an argument in the function which is the second parameter.</p>

<p>The function is only called once all the dependencies are loaded.</p>

<p>Here's the Wheel module:</p>

<pre><code>define([], function () {  
    var Wheel = function () {
        this._diameter = 10;
    };

    return Wheel;
});
</code></pre>

<h4 id="thatsall">That's all!</h4>

<p>That should be all you need to setup and use <em>require</em> for your web app!</p>]]></content:encoded></item><item><title><![CDATA[Box2d Collisions Made Easy (With Isogenic Engine)]]></title><description><![CDATA[<p>Isogenic Engine's box2d component got a boost today by making it really super easy to handle collisions between entities.</p>

<p>Say you have your player entity:</p>

<pre><code>var player = new IgeEntityBox2d()  
    .id('player');
</code></pre>

<p>You have some enemies too:</p>

<pre><code>var enemy = new IgeEntityBox2d()  
    .id('enemy1')
    .category('enemy');
</code></pre>

<p>You need to know when an</p>]]></description><link>http://blog.irrelon.com/box2d-collisions-made-easy/</link><guid isPermaLink="false">2e701172-3fb1-4858-8323-74616747f45d</guid><dc:creator><![CDATA[Rob Evans]]></dc:creator><pubDate>Sun, 23 Mar 2014 18:35:44 GMT</pubDate><content:encoded><![CDATA[<p>Isogenic Engine's box2d component got a boost today by making it really super easy to handle collisions between entities.</p>

<p>Say you have your player entity:</p>

<pre><code>var player = new IgeEntityBox2d()  
    .id('player');
</code></pre>

<p>You have some enemies too:</p>

<pre><code>var enemy = new IgeEntityBox2d()  
    .id('enemy1')
    .category('enemy');
</code></pre>

<p>You need to know when an enemy collides with your player. Using vanilla box2d you would register a contact listener, examine the contact for information about the two bodies that collided and then decide if a collision occurred.</p>

<p>In comparison with the new IGE update you can now do this:</p>

<pre><code>player.on('collisionStart', '.enemy', function (contactData) {  
    // Do whatever you want here
});
</code></pre>

<p>You can also hook when a contact ends:</p>

<pre><code>player.on('collisionEnd', '.enemy', function (contactData) {  
    // Do whatever you want here
});
</code></pre>

<p>You'll notice the '.enemy' selector in the call to "on()". This is the target selector that must match the entity being collided with for the event to fire. If you want to reference an entity via id instead of category, use the # symbol instead:</p>

<pre><code>player.on('collisionStart', '#enemy1', function (contactData) {  
    // Do whatever you want here
});
</code></pre>

<p>Awesome! :) - Available now on the premium repo dev branch version 1.5.5.</p>]]></content:encoded></item></channel></rss>