<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<feed xmlns="http://www.w3.org/2005/Atom">

	<title>SourceGear Blogs</title>
	<link rel="self" href="http://sourcegear.com/atom.xml"/>
	<link href="http://sourcegear.com/"/>
	<id>http://sourcegear.com/atom.xml</id>
	<updated>2013-06-19T11:00:02+00:00</updated>
	<generator uri="http://www.planetplanet.org/">Planet/2.0 +http://www.planetplanet.org</generator>

	<entry>
		<title type="html">Handling Simultaneous Updates in Zumero: There Is No Step 2</title>
		<link href="http://blog.roub.net/2013/05/handling-simultaneous-updates-in-zumero-there-is-no-step-2.html"/>
		<id>http://blog.roub.net/2013/05/handling-simultaneous-updates-in-zumero-there-is-no-step-2</id>
		<updated>2013-05-01T14:51:00+00:00</updated>
		<content type="html">&lt;p&gt;When we talk about the advantages of &lt;a href=&quot;http://www.ericsink.com/entries/crud.html&quot; title=&quot;Keep your CRUD off the Internet&quot;&gt;always-local data for mobile apps&lt;/a&gt;, the typical first reaction is &amp;#8220;that sounds awesome&amp;#8221;.&lt;/p&gt;

&lt;p&gt;The next step is to start thinking about your apps, and how mobile users interact with your data, and how those users aren&amp;#8217;t going to sit down and coordinate with each other:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&amp;#8220;It&amp;#8217;s my turn to update the inventory records for store #42&amp;#8221;&lt;/p&gt;

&lt;p&gt;&amp;#8220;Done with those yet?&amp;#8221;&lt;/p&gt;

&lt;p&gt;&amp;#8220;Yep, go ahead and sync.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&amp;#8220;Cool, thanks. Now I can update the ordered-quantity data.&amp;#8221;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;(a) That&amp;#8217;s not how work gets done, (b) computers are supposed to take care of picky details for us, and (c) I don&amp;#8217;t want to hang out with those guys at &lt;em&gt;all&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Dealing with this scenario in a Zumero-enabled app boils down to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users update and add data as they see fit.&lt;/li&gt;
&lt;li&gt;At some point, probably in the background, the app syncs to the server.&lt;/li&gt;
&lt;li&gt;Up-to-date, merged data now lives on the device.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You don&amp;#8217;t have to write any code that knows conflicting changes happened. Seriously. That&amp;#8217;s our problem.&lt;/p&gt;

&lt;p&gt;Even when the changes are tricky.&lt;/p&gt;

&lt;p&gt;Consider the &lt;a href=&quot;https://github.com/zumero/wiki&quot;&gt;Zumero wiki sample app&lt;/a&gt;. A wiki is a collaborative tool. People can, will, should edit the same pages. Sometimes at the same time.&lt;/p&gt;

&lt;p&gt;What happens if they do? Andy creates a page on his iPad:&lt;/p&gt;

&lt;p class=&quot;shot&quot;&gt;&lt;img alt=&quot; &quot; src=&quot;http://blog.roub.net/i/ipad-initial.png&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Colin pulls up the app on his iPhone, syncs, and gets his own copy. While offline, he adds a line to the page:&lt;/p&gt;

&lt;p class=&quot;shot&quot;&gt;&lt;img alt=&quot; &quot; src=&quot;http://blog.roub.net/i/iphone-added.png&quot; /&gt;&lt;/p&gt;


&lt;p&gt;At the same time, Andy completes one of the items on his list, and marks that line as completed.&lt;/p&gt;

&lt;p class=&quot;shot&quot;&gt;&lt;img alt=&quot; &quot; src=&quot;http://blog.roub.net/i/ipad-completed.png&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Colin comes back online, his app checks in and syncs, and he sees this:&lt;/p&gt;

&lt;p class=&quot;shot&quot;&gt;&lt;img alt=&quot; &quot; src=&quot;http://blog.roub.net/i/iphone-merged.png&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Here&amp;#8217;s the code that caused their apps to reconcile the conflicting updates:&lt;/p&gt;

&lt;span&gt;Sync a Zumero database &lt;/span&gt;&lt;a href=&quot;https://github.com/zumero/wiki/blob/master/Zumero%20Wiki/ZWMasterViewController.m&quot;&gt;link&lt;/a&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;objective-c&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_db&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;sync:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scheme&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;user:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;password:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;error:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;There&amp;#8217;s no step 2.&lt;/p&gt;

&lt;p&gt;To be fair, there were a couple of lines of code that ran when we initially set up the database, which boiled down to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If there are conflicting edits on the &amp;#8216;text&amp;#8217; field of a wiki page, try to merge them, Zumero. Thanks.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;No step 2.&lt;/p&gt;</content>
		<author>
			<name>Paul Roub</name>
			<uri>http://blog.roub.net/</uri>
		</author>
		<source>
			<title type="html">Paul Roub</title>
			<subtitle type="html">a software tool geek in his natural habitat</subtitle>
			<link rel="self" href="http://blog.roub.net/atom.xml"/>
			<id>http://blog.roub.net/</id>
			<updated>2013-05-01T16:00:02+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Keep your CRUD off the Internet</title>
		<link href="http://www.ericsink.com/entries/crud.html"/>
		<id>http://www.ericsink.com/entries/crud.html</id>
		<updated>2013-04-23T15:00:01+00:00</updated>
		<content type="html">&lt;p&gt;Whenever I explain database sync for mobile, somebody asks,
&quot;What kinds of apps would benefit from that?&quot;&lt;/p&gt;

&lt;p&gt;The correct answer is:  &quot;ALL apps&quot;.&lt;/p&gt;

&lt;p&gt;Actually, that's an exaggeration.  I see no reason for my alarm clock or
calculator apps to sync data with a server.  Let me rephrase:

&lt;p&gt;&lt;b&gt;Sync
    is the best architecture&lt;br /&gt;for apps where a
database and a server are involved&lt;/b&gt;.&lt;/p&gt;

&lt;h3&gt;CRUD over REST is an Anti-Pattern&lt;/h3&gt;

&lt;p&gt;Many apps today keep the data only on the server and access it using REST.
This approach has some big negative consequences:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;

    &lt;p&gt;&lt;b&gt;Performance&lt;/b&gt;:  Your app is less responsive.&lt;/p&gt;

    &lt;p&gt;A round-trip from a mobile device to a server takes a LONG time.  Under
    good network conditions, it could be a quarter of a second.  That's enough time for the
    user to perceive a lag.&lt;/p&gt;

    &lt;p&gt;Sometimes the round-trip will take longer, more like a full second, or more.
    That's an eternity, a one-star review in the App Store.&lt;/p&gt;

    &lt;p&gt;Numerous studies show that when it comes to the responsiveness of a
    user interface, fractions of a second matter a LOT.  And people don't
    necessarily complain about your app.  They just stop
    using it.&lt;/p&gt;

    &lt;p&gt;If you're going to make a round-trip to the server in response to a user
    action, your app is going to feel sluggish.&lt;/p&gt;

    &lt;/li&gt;

    &lt;li&gt;

    &lt;p&gt;&lt;b&gt;Reliability&lt;/b&gt;:  Your app doesn't work offline.&lt;/p&gt;

    &lt;p&gt;WiFi is great, but not everything is a coffee shop.&lt;/p&gt;

    &lt;p&gt;Cellular data networks have dead spots, sometimes in surprising places. 
    Even in areas with solid 3G or LTE coverage, the latency varies wildly.&lt;/p&gt;

    &lt;p&gt;If your app is going to stop working when the wireless network is
    unavailable or unreliable, then your app is going to stop working a lot.&lt;/p&gt;

    &lt;/li&gt;

    &lt;li&gt;

    &lt;p&gt;&lt;b&gt;Complexity&lt;/b&gt;:  Your app's code has to deal with networking issues everywhere.&lt;/p&gt;

    &lt;p&gt;People wrap their REST calls in pretty wrappers to make them look like networking is not involved.
    But it is.
    A robust app needs to deal with all the things that can go wrong.&lt;/p&gt;

    &lt;p&gt;If you're going to do all your basic database operations over a REST API,
    all your code is networking code.&lt;/p&gt;

    &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real question is &quot;What kinds of apps would benefit from having user interaction
dependent on a wireless network with inconsistent coverage and random latency spikes?&quot;&lt;/p&gt;

&lt;p&gt;Your app does lots of basic database operations which are often referred to as &lt;a href=&quot;http://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD&lt;/a&gt;
(Create, Read, Update, Delete).  These operations do not want to happen over a
network.  They want to happen in a database which is local, on the mobile device.&lt;/p&gt;

&lt;p&gt;And so you need sync.  In the background (so the user doesn't have to wait on it).
With automatic conflict resolution.&lt;/p&gt;

&lt;p&gt;And that's hard.&lt;/p&gt;

&lt;h3&gt;Solutions that make sync easy&lt;/h3&gt;

&lt;p&gt;Do you like SQL?  If so, I invite you to look at &lt;a href=&quot;http://zumero.com&quot;&gt;Zumero&lt;/a&gt;, our database sync platform based on SQLite, the relational database software preinstalled on over a billion mobile devices.&lt;/p&gt;

&lt;p&gt;Do you prefer NoSQL?  Then I'm sure our worthy competitors over at Couchbase would be happy for you to look at &lt;a href=&quot;https://github.com/couchbase/couchbase-lite-ios/wiki/Why-Couchbase-Lite%3F&quot;&gt;Couchbase Lite&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Either way, keep your CRUD off the Internet.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Eric.Weblog()</name>
			<uri>http://www.ericsink.com/</uri>
		</author>
		<source>
			<title type="html">Eric Sink</title>
			<subtitle type="html">SourceGear Founder</subtitle>
			<link rel="self" href="http://www.ericsink.com/rss.xml"/>
			<id>http://www.ericsink.com/rss.xml</id>
			<updated>2013-04-23T15:00:01+00:00</updated>
			<rights type="html">Copyright 2001-2013 Eric Sink. All Rights Reserved</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Announcing Zumero SQLite for Xamarin</title>
		<link href="http://www.ericsink.com/entries/zumero_sqlite_for_xamarin.html"/>
		<id>http://www.ericsink.com/entries/zumero_sqlite_for_xamarin.html</id>
		<updated>2013-04-14T17:00:00+00:00</updated>
		<content type="html">&lt;p&gt;I am pleased to announce that &lt;a href=&quot;http://components.xamarin.com/view/zumero/&quot;&gt;Zumero SQLite&lt;/a&gt; is now available in the Xamarin Component Store.  It's free, and it supports Android and iOS.&lt;/p&gt;

&lt;p&gt;Zumero SQLite for Xamarin starts with the core &quot;replicate and sync&quot; functionality from the Zumero Client SDK and adds:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;p&gt;ADO.NET -- Familiar C# API for SQL developers.  (provided by &lt;a href=&quot;http://system.data.sqlite.org&quot;&gt;System.Data.SQLite&lt;/a&gt;, which is maintained by the same folks who develop SQLite itself)&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p&gt;Full-database encryption -- Critical piece of the &quot;replicate and sync&quot; story.  Mobile devices get lost.  (provided by the excellent &lt;a href=&quot;https://github.com/sqlcipher/sqlcipher&quot;&gt;SQLCipher&lt;/a&gt; library)&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p&gt;Painless setup -- Install the component and you've got everything you need.  (provided by the neato component store feature of Xamarin Studio)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Comfy&lt;/h3&gt;

&lt;p&gt;In some ways, the core of the Zumero Client SDK is not very easy to use.
That is intentional.  It is designed to be the sort of SDK that leaves many things
as the responsibility of the app (or the next layer up).&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;p&gt;It doesn't actually include SQLite itself, since the app might care about which version of SQLite it wants, or how it needs to be compiled.&lt;/p&gt;&lt;/li&gt;

    &lt;li&gt;&lt;p&gt;It doesn't include any page-level encryption support, since it doesn't know whether the app wants to use SQLCipher or the &lt;a href=&quot;http://www.hwaci.com/sw/sqlite/see.html&quot;&gt;SQLite Encryption Extension&lt;/a&gt; or something else.&lt;/p&gt;&lt;/li&gt;

    &lt;li&gt;&lt;p&gt;It plugs into SQLite using C, because that's the native language that SQLite uses for its API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Power users and control freaks need this kind of SDK.  And it comes
first, since everything else is built on top of it.  But most
users want an experience that is more &quot;comfy&quot;.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;p&gt;They don't want to think about versions of SQLite or compile options for same.&lt;/p&gt;&lt;/li&gt;

    &lt;li&gt;&lt;p&gt;They don't want to choose an encryption library and figure out how to integrate it with their app.&lt;/p&gt;&lt;/li&gt;

    &lt;li&gt;&lt;p&gt;They don't want to write their mobile app in C.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Zumero Client SDK actually does include some carpeting and furniture on top of that cold, hard C floor.  For
Android developers using Java, it presents the android.database.sqlite API.  And
for iOS developers using Objective-C, it offers a wrapper that lets you work
with things that have NS prefixes.&lt;/p&gt;

&lt;p&gt;(Which reminds me, check out our &lt;a href=&quot;https://github.com/zumero/wiki&quot;&gt;iOS wiki app&lt;/a&gt; sample on
GitHub.)&lt;/p&gt;

&lt;p&gt;Anyway, these efforts are just the beginning.
Our direction is toward &quot;comfy&quot;, and we are moving fast.&lt;/p&gt;

&lt;p&gt;This component for Xamarin is a step forward, and I think it is an important
one.&lt;/p&gt;

&lt;h3&gt;Samples&lt;/h3&gt;

&lt;p&gt;This new component includes three sample apps, all of which are modified versions of samples provided by Xamarin.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;p&gt;Data (iOS, based on &lt;a href=&quot;https://github.com/xamarin/monotouch-samples/tree/master/Data&quot;&gt;https://github.com/xamarin/monotouch-samples/tree/master/Data&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p&gt;Notepad (Android, based on &lt;a href=&quot;https://github.com/xamarin/monodroid-samples/tree/master/NotePad-Mono.Data.Sqlite&quot;&gt;https://github.com/xamarin/monodroid-samples/tree/master/NotePad-Mono.Data.Sqlite&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
    &lt;li&gt;&lt;p&gt;Tasky (cross-platform, based on &lt;a href=&quot;https://github.com/xamarin/mobile-samples/tree/master/Tasky&quot;&gt;https://github.com/xamarin/mobile-samples/tree/master/Tasky&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Data and Notepad samples have simply been ported to System.Data.SQLite
(which involved very few changes).&lt;/p&gt;

&lt;p&gt;The Tasky sample goes a bit further and adds a very simple ability to sync the
task list.&lt;/p&gt;

&lt;h3&gt;Evolve&lt;/h3&gt;

&lt;p&gt;I am in Austin for Xamarin's Evolve conference, which starts today.
Xamarin is doing some of the coolest stuff in mobile development today.  We are
thrilled to be a part of it.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content>
		<author>
			<name>Eric.Weblog()</name>
			<uri>http://www.ericsink.com/</uri>
		</author>
		<source>
			<title type="html">Eric Sink</title>
			<subtitle type="html">SourceGear Founder</subtitle>
			<link rel="self" href="http://www.ericsink.com/rss.xml"/>
			<id>http://www.ericsink.com/rss.xml</id>
			<updated>2013-04-23T15:00:01+00:00</updated>
			<rights type="html">Copyright 2001-2013 Eric Sink. All Rights Reserved</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Zumero: Background Sync in Objective-C</title>
		<link href="http://blog.roub.net/2013/04/zumero-background-sync-in-objective-c.html"/>
		<id>http://blog.roub.net/2013/04/zumero-background-sync-in-objective-c</id>
		<updated>2013-04-09T14:31:00+00:00</updated>
		<content type="html">&lt;h2&gt;Mobile offline RSS reader, Part 5&lt;/h2&gt;

&lt;p&gt;In the second &amp;#8220;crossover episode&amp;#8221; of our series (previous episodes begin on &lt;a href=&quot;http://www.ericsink.com/entries/rss_cat_1.html&quot; title=&quot;Using Zumero from C#&quot;&gt;Eric&amp;#8217;s blog&lt;/a&gt;), we look at background operations.&lt;/p&gt;

&lt;p&gt;Previously, we built &lt;a href=&quot;http://zumero.com/&quot;&gt;Zumero&lt;/a&gt; databases full of RSS lists and feed contents.  The &lt;a href=&quot;http://github.com/zumero/ZumeroReader&quot;&gt;ZumeroReader&lt;/a&gt; sample app pulls, reads and displays those feeds on iOS devices.  In action, it looks like this:&lt;/p&gt;

&lt;p class=&quot;shot&quot;&gt;&lt;img alt=&quot; &quot; src=&quot;http://blog.roub.net/i/ipadreader.png&quot; /&gt;&lt;/p&gt;


&lt;p&gt;At startup, it pulls the feed list like so:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;13&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;14&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;15&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;18&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;objective-c&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;ZumeroDB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ZumeroDB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;              &lt;span class=&quot;nl&quot;&gt;initWithName:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&amp;quot;all_feeds&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;              &lt;span class=&quot;nl&quot;&gt;folder:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;host:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;NSError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;kt&quot;&gt;BOOL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;YES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;createDB:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isOpen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;open:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;NSDictionary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scheme&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pwd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;sync:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scheme&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;user:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uname&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;password:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pwd&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;error:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;We&amp;#8217;re creating a Zumero database file named &amp;#8220;all_feeds&amp;#8221;. It will sync with a similarly-named dbfile on the server side.&lt;/p&gt;

&lt;p&gt;We don&amp;#8217;t need any authentication info, since (as &lt;a href=&quot;http://www.ericsink.com/entries/rss_cat_1.html&quot; title=&quot;Using Zumero from C#&quot;&gt;previously discussed&lt;/a&gt;) the feed lists and feed databases are pullable by anyone.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ZumeroDB::sync&lt;/code&gt; method &lt;em&gt;always&lt;/em&gt; performs its network activity on a background thread, calling delegate methods when the action is completed (hence &lt;code&gt;db.delegate = self&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In this case, on sync success, we grab the latest copies of the individual feed databases:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;13&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;14&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;15&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;18&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;19&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;21&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;22&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;23&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;24&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;objective-c&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;selectSql:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&amp;quot;select feeds.feedid, url, title from feeds, about &amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;s&quot;&gt;&amp;quot;where (feeds.feedid = about.feedid)&amp;quot;&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;values:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;nl&quot;&gt;rows:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;error:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSDictionary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;NSNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;objectForKey:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&amp;quot;feedid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;syncFeed:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;syncFeed:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feedid&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;stringWithFormat:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&amp;quot;feed_%@&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feedid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;ZumeroDB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ZumeroDB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;initWithName:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbname&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;folder:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;host:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;sync:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;user:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;password:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;error:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;But what if feeds are updated while the app is running?  There are seemingly infinite strategies for launching background tasks in iOS, and you&amp;#8217;ll use the one that fits your application best.  In this case, I cribbed a simple plan from a &lt;a href=&quot;http://stackoverflow.com/questions/273450/iphone-detecting-user-inactivity-idle-time-since-last-screen-touch&quot; title=&quot;iPhone: Detecting user inactivity/idle time since last screen touch&quot;&gt;StackOverflow post&lt;/a&gt; - every time a touch is detected, we restart a timer.  If that timer actually manages to expire, then we&amp;#8217;ve seen no touches in 5 seconds.&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;13&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;14&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;15&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;18&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;19&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;21&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;22&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;objective-c&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;sendEvent:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UIEvent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;sendEvent:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;n&quot;&gt;NSSet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;allTouches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allTouches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;allTouches&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;n&quot;&gt;UITouchPhase&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UITouch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;allTouches&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UITouchPhaseBegan&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UITouchPhaseEnded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;resetIdleTimer:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxIdleTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;resetIdleTimer:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSTimeInterval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;secs&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idleTimer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idleTimer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invalidate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;n&quot;&gt;idleTimer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;n&quot;&gt;idleTimer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSTimer&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;scheduledTimerWithTimeInterval:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;secs&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;               &lt;span class=&quot;nl&quot;&gt;target:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;selector:&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;@selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idleTimerExceeded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;               &lt;span class=&quot;nl&quot;&gt;userInfo:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;repeats:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;When that timer fires, we check to see if its been 5 minutes since our last sync, and that a sync is wanted. If so, we sync again:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;13&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;14&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;15&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;18&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;19&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;21&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;22&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;23&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;24&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;25&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;26&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;27&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;28&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;29&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;31&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;32&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;objective-c&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idleTimerExceeded&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wantToSync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;n&quot;&gt;NSTimeInterval&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;since&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextSync&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeIntervalSinceNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;since&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;n&quot;&gt;wantToSync&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;FALSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;kt&quot;&gt;BOOL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;FALSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;c1&quot;&gt;// the view controller's sync method from earlier          &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;              &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mvc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;              &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;networkActivityIndicatorVisible&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;YES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;              &lt;span class=&quot;c1&quot;&gt;// the sync call failed; try again later&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;              &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;waitForSync:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;c1&quot;&gt;// nope, check again next idle time&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;          &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;resetIdleTimer:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;since&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;resetIdleTimer:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxIdleTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;We also kill our timers when exiting, restart them when waking up or activating, etc.&lt;/p&gt;

&lt;p&gt;Finally, when we go into the background, we try for one last sync before our process is suspended:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;13&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;objective-c&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;applicationDidEnterBackground:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UIApplication&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;bgtask&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;beginBackgroundTaskWithExpirationHandler:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;endBackgroundTask:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bgtask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;n&quot;&gt;bgtask&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UIBackgroundTaskInvalid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;p&quot;&gt;}];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;n&quot;&gt;dispatch_async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dispatch_get_global_queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;n&quot;&gt;DISPATCH_QUEUE_PRIORITY_DEFAULT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mvc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;c1&quot;&gt;// finishBackgroundTask will be called by the sync handlers&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;Like any good sample app, there&amp;#8217;s so much that this app &lt;em&gt;doesn&amp;#8217;t&lt;/em&gt; do.  You&amp;#8217;re invited to experiment with adding them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We don&amp;#8217;t maintain any read/unread information, either at the feed level or for individual items.
This would be a good place to try creating/syncing new databases.&lt;/li&gt;
&lt;li&gt;We naïvely grab the first &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; element we see and assume that it&amp;#8217;s our permalink, without ever
checking its &lt;code&gt;rel&lt;/code&gt; attribute or content type.&lt;/li&gt;
&lt;li&gt;A feed&amp;#8217;s contents are displayed as one big chunk of HTML. Individual table cells might be nice.&lt;/li&gt;
&lt;li&gt;We don&amp;#8217;t make any attempt to become a long-running background process, since we don&amp;#8217;t actually play audio, collect
location information, etc. Might be fun to play with that.&lt;/li&gt;
&lt;li&gt;Configuring the app is done by editing the source and rebuilding. That seems rude.&lt;/li&gt;
&lt;li&gt;If you &lt;em&gt;did&lt;/em&gt; update some sort of last-read database, wouldn&amp;#8217;t that be a great moment to kick off a background sync? (The &lt;a href=&quot;https://github.com/zumero/wiki&quot;&gt;Wiki&lt;/a&gt; app included in the &lt;a href=&quot;http://zumero.com/dev-center&quot;&gt;Zumero SDK&lt;/a&gt; does this when a page is created or saved)&lt;/li&gt;
&lt;/ol&gt;</content>
		<author>
			<name>Paul Roub</name>
			<uri>http://blog.roub.net/</uri>
		</author>
		<source>
			<title type="html">Paul Roub</title>
			<subtitle type="html">a software tool geek in his natural habitat</subtitle>
			<link rel="self" href="http://blog.roub.net/atom.xml"/>
			<id>http://blog.roub.net/</id>
			<updated>2013-05-01T16:00:02+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Altering a Zumero Table</title>
		<link href="http://blog.roub.net/2013/04/altering-a-zumero-table.html"/>
		<id>http://blog.roub.net/2013/04/altering-a-zumero-table</id>
		<updated>2013-04-09T14:26:00+00:00</updated>
		<content type="html">&lt;h2&gt;Mobile offline RSS reader, Part 4&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&quot;http://www.ericsink.com/entries/rss_cat_3.html&quot; title=&quot;Zumero: Efficient sync by using multiple SQLite files&quot;&gt;part 3&lt;/a&gt; of this series, Eric discussed three programs that do the back-end work
of RSS aggregation - scanning feed lists, caching summaries and IDs, creating data files as
we go.&lt;/p&gt;

&lt;p&gt;Before we get into &lt;em&gt;using&lt;/em&gt; that information in part 5, we need to adjust one of the schemas a bit.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;items&lt;/code&gt; table in each feed&amp;#8217;s database is set up as:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;sql&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VIRTUAL&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;k&quot;&gt;USING&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zumero&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;TEXT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;TEXT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;TEXT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;n&quot;&gt;pubdate_unix_time&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INTEGER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;Where the &lt;code&gt;id&lt;/code&gt; field comes from the feed items&amp;#8217;s &lt;code&gt;id&lt;/code&gt; or &lt;code&gt;guid&lt;/code&gt; element, or from the first &lt;code&gt;link&lt;/code&gt;
found in the entry.  In many RSS feeds, &lt;code&gt;id&lt;/code&gt; will also be the permalink to the entry&amp;#8217;s
&amp;#8220;destination&amp;#8221;, e.g.&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;xml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Enterprise mobile will have a lot of SQL going on&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;nt&quot;&gt;&amp;lt;guid&amp;gt;&lt;/span&gt;http://www.ericsink.com/entries/mobile_sql.html&lt;span class=&quot;nt&quot;&gt;&amp;lt;/guid&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;But that&amp;#8217;s not mandatory. For example:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;xml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;entry&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;nt&quot;&gt;&amp;lt;id&amp;gt;&lt;/span&gt;http://zumero.com/2013/04/04/just-released-the-zumero-development-server&lt;span class=&quot;nt&quot;&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;alternate&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;   &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://zumero.com/2013/04/04/just-released-the-zumero-development-server.html&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Just Released: the Zumero Development Server&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;  ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;We still want that unique &lt;code&gt;id&lt;/code&gt;, but if a link is available, we&amp;#8217;ll want to store that, too.&lt;/p&gt;

&lt;p&gt;Easy enough when creating a new &lt;code&gt;items&lt;/code&gt; table. We&amp;#8217;ll alter &lt;a href=&quot;https://github.com/paulroub/z_rss/blob/master/z_rss_create.cs&quot;&gt;&lt;code&gt;z_rss_create.cs&lt;/code&gt;&lt;/a&gt; to read:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;c#&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;s&quot;&gt;@&amp;quot;CREATE VIRTUAL TABLE &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;        cur.items &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;        USING zumero&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;        (&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;          id TEXT PRIMARY KEY NOT NULL, &lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;          title TEXT NOT NULL,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;          summary TEXT NOT NULL,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;          pubdate_unix_time INTEGER NOT NULL,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;          permalink TEXT&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;        );&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;But what about &lt;code&gt;items&lt;/code&gt; tables that already exist? Unfortunately, SQLite &lt;a href=&quot;http://www.sqlite.org/vtab.html&quot; title=&quot;The Virtual Table Mechanism Of SQLite&quot;&gt;does not allow&lt;/a&gt; &lt;code&gt;alter table ... add column&lt;/code&gt; to run against a virtual table like Zumero&amp;#8217;s.  We&amp;#8217;ll use the Zumero-provided alternative, &lt;a href=&quot;http://zumero.com/docs/zumero_core.html#chapter_functions&quot;&gt;&lt;code&gt;zumero_alter_table_add_column()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;https://github.com/paulroub/z_rss/blob/master/z_rss_update.cs&quot;&gt;&lt;code&gt;z_rss_update.cs&lt;/code&gt;&lt;/a&gt;, we&amp;#8217;ll see if the new column already exists:&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;c#&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;pragma cur.table_info(\&amp;quot;items\&amp;quot;)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SQLiteConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SQLiteConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;n&quot;&gt;found&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Compare&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;permalink&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringComparison&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;found&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;If not&amp;#8230;&lt;/p&gt;

&lt;span&gt;&lt;/span&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&quot;line-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;line-number&quot;&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;c#&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;BEGIN TRANSACTION;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ExecuteScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&amp;quot;select zumero_alter_table_add_column(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;s&quot;&gt;   'cur', 'items', 'permalink TEXT');&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;COMMIT TRANSACTION;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// after altering a zumero table, the dbfile connection must be reopened&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;DETACH cur;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbfile_name_for_this_feed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ATTACH ? AS cur;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbfile_name_for_this_feed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


&lt;p&gt;See &lt;a href=&quot;https://github.com/paulroub/z_rss&quot;&gt;this fork&lt;/a&gt; of &lt;code&gt;z_rss&lt;/code&gt; for all the necessary code.&lt;/p&gt;

&lt;p&gt;In part 5, we&amp;#8217;ll see a simple iOS RSS reader that pulls these databases in the background, and
lets you browse the feed summaries and link through to the full articles.&lt;/p&gt;</content>
		<author>
			<name>Paul Roub</name>
			<uri>http://blog.roub.net/</uri>
		</author>
		<source>
			<title type="html">Paul Roub</title>
			<subtitle type="html">a software tool geek in his natural habitat</subtitle>
			<link rel="self" href="http://blog.roub.net/atom.xml"/>
			<id>http://blog.roub.net/</id>
			<updated>2013-05-01T16:00:02+00:00</updated>
		</source>
	</entry>

</feed>
