The Scriptures for the iPhone at WWDC

June 15th, 2009

Dave DeLong was nice enough to send me this picture of the icon for The Scriptures as seen on the App Store video wall at WWDC:

scripturesWWDC.png

The Future of the Scriptures for the iPhone

March 10th, 2009

When I first purchased my iPhone, one of the first things that I wanted to do was install a portable copy of The Scriptures. There were lots of programs available for windows mobile and Palm devices for this, but as the iPhone as just starting to allow 3rd party development, there still wasn’t anything available for it.

After releasing the application I started to receive lots of feedback and ideas about ways to make it better, and because of the importance of what the application represented to so many people, I tried to incorporate as many of the suggestions that I felt were appropriate and that I had time for given my limited availability.

As time went on there were two big items that lots of people wanted that were proving to be difficult:

  1. More content
  2. People suggested everything from hymns to class manuals to old conference talks. The roadblock here of course is one of copyright. While it is okay to reproduce most of the materials in question for personal use, some of them (the hymns for example) have very tricky copyright issues involved. There is also the question of whether a 3rd party distributing the items for personal use was still ok.

  3. Localizations
  4. While the vast majority of the users were in the US (around 40,000), there were still several thousand outside of the US that were interested in having the Scriptures available in their own native languages. (Not to mention US residents whose native language isn’t English)

    At first this seemed like it would be trivial because of the number of willing beta testers that I had who spoke foreign languages, and the standardized format the the Church uses for maintaing the Scriptures online in multiple languages. However there are lots of issues with parsing non-english text that come up when you’re trying to take a bunch of raw html data and convince it to conform to a normalized database structure. Because of the sacred nature of the Scriptures, this isn’t something that you would want to mess up.

These two obstacles not withstanding, I still felt this was an important project that I didn’t just want to give up on. Fortunately something happened a few weeks ago that provided a solution. I received an email from Tom Welch of the LDS Tech community that contained an announcement saying that the Church was developing (among other things) its own iPhone Scriptures Application. I immediately contacted him and offered to donate all of the source code from my project and am happy that he accepted.

I don’t know how much (if any) of the actual code will be used in the final official church project. I am excited to see the Church continuing to embrace new technology as a method of spreading the Gospel as they have done so many times before.

So this, sadly, marks the official end of my iPhone Scriptures Application project. The application will still remain available for download in its current form until the Church releases their own. Anyone wishing to assist with the project should look at the LDS Tech wiki pages for the project and contact Tom Welch via email.

Thanks for everyone who sent in words of encouragement and support. Also thanks to everyone that helped out with beta testing and offered to assist with localizations. This has been a wonderful experience and I have been blessed in so many ways because of it.

The Scriptures 1.1.1

December 21st, 2008

The Scriptures for the iPhone and iPod Touch version 1.1.1 is now available for download from the App Store. You can read about the changes here.

iPhone SQLite Database Basics - Part 2

December 11th, 2008

After writing the article on iPhone SQLite Database Basics, I received lots of followup questions and comments, some of which I will discuss here.

SQLite Database Creation

In my first article I wrote that the easiest way to work with SQLite databases on the mac was the SQLite extension for Firefox.

Since then, my attention has been brought to Menial’s Base application. This is the application that I now use for all of my SQLite work. It is super fast, and has an interface that is extremely easy to use. It also has a lot of nice touches that make it more Mac-like than using a Firefox extension. If you’re doing SQLite work on the Mac, I strongly recommend that you check it out.

Making a Writable Copy of the Database

In the first part of this tutorial, I mentioned that if you needed to write to your database you needed to copy it to a location that you could write to.

A couple of people have asked how to do this. To answer that, I first want to talk a little bit about how to control SQLite access in Cocoa applications. There are really three ways to do this:

  1. Have DB access code in each class that needs it (bad)
  2. Have you application delegate handle all DB access for you (better)
  3. Use a singleton object for your DB access (best)

For more about the tradeoffs between application delegate usage and singleton objects see this post from Cocoa with Love.

If you are using the singleton pattern, then you can make a writable copy of your database in your singleton object’s allocation method, using something like this:

  1. -(NSString*)createWriteableDB
  2. {
  3.     // See if writeable database already exists
  4.     NSFileManager *fileManager = [NSFileManager defaultManager];
  5.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  6.     NSString *documentsDirectory = [paths objectAtIndex:0];

  7.     NSString *readOnlyDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseFileName];
  8.     NSString *writableDBPath = [[documentsDirectory stringByAppendingPathComponent:self.databaseFileName] retain];

  9.     // First time install
  10.     if(![fileManager fileExistsAtPath:writableDBPath])
  11.     {
  12.         if(![fileManager copyItemAtPath:readOnlyDBPath toPath:writableDBPath error:&self.lastError])
  13.         {
  14.             NSAssert1(0, @”Failed to create writable database file with message ‘%@’.”, [self.lastError localizedDescription]);
  15.             return nil;
  16.         }
  17.     }

  18.     return [writableDBPath autorelease];
  19. }

A couple of important things to note here:

If you have a very large database and the things that you need to allow the user to update, (i.e. bookmarks, or annotations) are small in comparison, it may be better for you to have two databases files, one that contains the data that won’t change, and the other that contains the data used for annotations. This way you won’t have two large copies of the database on the user’s device.

This will of course have a large impact on your query design, and some database purists may be lining up to lynch me, but as I mentioned in the first article, there are some SQLite considerations that are unique to mobile devices like the iPhone.

Another thing to consider is versioning. You need to be very careful how you handle application updates that change the database structure and/or content when you are allowing the user to write data (that presumably they want to persist between updates).

One way to handle this is to simply have a table in your writable database called “Version” which contains one row and one column with the version number of the database schema.

Then in the above code you can add some logic to transfer the data from a pervious schema version to the new writable database file.

Third Party SQLite Wrappers

There are lots of SQLite wrappers available for iPhone development. I’ve never used any so I can’t say if any one is better than another. If the idea of using c-based SQLite calls makes you anxious, you may want to check them out.

Security

Someone suggested that I point out that SQLite databases on the iPhone aren’t really secure. I’m not a database security expert, but that statement is true of databases on any platform. The database is only as secure as the device itself. If someone gets ahold of your iPhone, they can most likely get the data off of it.

The Scriptures 1.1.0

December 8th, 2008

The Scriptures for the iPhone and iPod Touch version 1.1.0 is now available for download from the App Store. You can read about the changes here.

What happened to Landscape mode?

Previous version of The Scriptures application had the useful (and expected) feature of being able to rotate the device to read in landscape mode. Unfortunately due to some technical issues, some of the new features in this version made this feature a bit buggy. Some of these issues were design related, others have to do with a known bug regarding how the iPhone SDK handles rotations.

Rather than deliver a substandard user experience, I have pulled this feature until I can fix the issues associated with it.

iPhone SQLite Database Basics

October 2nd, 2008

In celebration of the lifting of the NDA on the iPhone SDK, I decided to write a tutorial on using SQLite on the iPhone.

This tutorial covers the basics of SQLite database creation, things to consider in the design of the database, and some particular things to be aware of when deploying these types of applications to the iPhone.

Once you have finished with these basics, take a look at the SQLiteBooks sample code from the iPhone dev center for details on how to interface with the database from your code.

Step 1: Create a SQLite Database File

There are lots of ways to create a SQLite database file. The easiest way that I have found is to download the SQLite Firefox extension, which provides a GUI to create and manage your SQLite database. The rest of this tutorial will assume you have that extension installed.

In this tutorial we’ll be creating a recipe application, so we are naming our database “recipes”.

To create the database:

  1. Click the “New Database” toolbar button.
  2. Enter the name of the database file.
  3. Click OK.

createDB.jpg

You will then be prompted for a location to save the database. The ideal place is in the directory of your XCode project.

Step 2: Create the Database Schema

Now we are going to setup our database tables. This will be a very simple database with two tables:

schema.png

There are entire textbooks about “proper” database design and if you are developing a super large-scale ultra robust data warehouse app, you might want to look them over. However rather than make your eyes glaze over with the merits of third normal form, let me just share a few guidelines that I picked up during several years as a DBA/Database application developer:

  1. Every table should mirror an object, with each non-calculated object property mapping directly to a table field.
  2. In addition to the object properties, every table should have an integer field that is autofilled with a unique identifier (commonly know as the primary key).
  3. Every table that is dependent on a parent table should have a way to refer back to its parent. (This is sometimes called a Foreign Key)

In our application we’re going to have two model objects. A Recipe object, and an Ingredient object. Each recipe object can have 1 or more ingredient child objects. (The blue arrow in the above diagram signifies this, and is called a 1-to many relationship).

The Recipe object has a name and description property. These are both strings, and these map to database fields of type VarChar (meaning Variable length Character string). In addition, the Recipes table has a Recipe_ID field of type Integer. This field is the primary key of the Recipes table.

The ingredient object in our simple application only has one property, Description. Since this is a string it also maps to a VarChar field. Our Ingredients table also has a primary key (Ingredient_ID) which gives us a way to refer to a specific ingredient.

Finally, the Recipe_ID field in the Ingredients table is our foreign key back to the Recipes table. Using that key you can look at any ingredient and know what Recipe it belongs to. More commonly an application will use that key to get all of the ingredients that belong to a specific recipe.

To create the Recipes table, click the “New Table” toolbar button and enter the information as seen below:

RecipeTable.jpg

Notice that we check the Primary Key and Autoinc checkboxes for the Recipe_ID field. The Primary Key checkbox tells SQLite to treat this field as a Unique Index, meaning that it can guarantee that the values in this field won’t be duplicated and should be kept sorted for faster queries. (Later we’ll talk a little more about optimizing queries by adding additional table indices.)

The Autoinc checkbox tells SQLite how to handle the automatic creation of primary key values. Without autoinc being checked, when a new row is added SQLite sets the primary key to one greater than the current highest primary key. With the box checked, SQLite sets the primary key to one greater than the highest primary key that the table has every had. (Which it keeps track of in its own table called sqlite_sequence). How you set this box will depend on how you want to handle deleted records.

For the Ingredients table, it is much the same:

IngredientsTable.jpg

Notice that we do NOT mark the Recipe_ID field of the Ingredients table as a primary key. It is the primary key of the Recipes table, not of this table. (In this table some people would call the Recipe_ID field the foreign key).

The last thing that we want to do regarding our database schema is to create an index on the Recipe_ID field of the Ingredients table. Since most of our queries that involve this table will involve looking up a specific value in the Recipe_ID field, it will speed things up to have an index on this field. (Note: You really won’t notice a significant speed increase unless your Ingredients table has a lot of records, but since it is a good design principle, we’re going to do it anyway.)

createIndex.jpg

Finally you need to populate the table with some data. You can do that using the SQLite Manager by selecting the table and then clicking the “Add new Record” button, or by selecting the “Execute SQL” tab and using several Insert statements.

For example to insert this data into my Recipes table:

Recipe_ID Name Description
1 Omelet A delicious and eggy breakfast.
2 Grilled Cheese Sandwich A delicious and cheese filled lunch.
3 Pizza A classic dinner from the old world.

I could use these three insert statements:

INSERT into Recipes(Name, Description) VALUES(’Omelet’, ‘A delicious and eggy breakfast.’);
INSERT into Recipes(Name, Description) VALUES(’Grilled Cheese Sandwich’, ‘A delicious and cheese filled lunch.’);
INSERT into Recipes(Name, Description) VALUES(’Pizza’, ‘A classic dinner from the old world.’);

Notice that I did not insert the values for the Recipe_ID field. As I mentioned above, since it is the primary key the database calculates those values automatically.

Next comes the Ingredients table:

Ingredient_ID Recipe_ID Description
1 1 Eggs
2 1 Water
3 1 Salt
4 2 Bread
5 2 Cheese
6 2 Butter
7 3 Pizza Dough
8 3 Pizza Sauce
9 3 Cheese
10 3 Toppings

Which I could use the following statements for:

INSERT into Ingredients(Recipe_ID, Description) VALUES(1, ‘Eggs’);
INSERT into Ingredients(Recipe_ID, Description) VALUES(1, ‘Water’);
INSERT into Ingredients(Recipe_ID, Description) VALUES(1, ‘Salt’);
INSERT into Ingredients(Recipe_ID, Description) VALUES(2, ‘Bread’);
INSERT into Ingredients(Recipe_ID, Description) VALUES(3, ‘Toppings’);

Again notice that I did not specify the values for the table’s primary key (Ingredient_ID), but I did specify the foreign key values (Recipe_ID).

Step 3: Add the Database File to Your XCode Project

To do this, just right click on the Resources folder and select “Add->Existing Files…” and then select the database file that you created.

addFile.jpg

XCode should automatically add the file that you select to the “Copy Bundle Resources” build phase of your project target. (Meaning that when the program is compiled, your database file is automatically stored in the application bundle’s resource folder so that you can access it from your application.)

Update: Jonathan Wight suggested that instead of embedding the SQLite db file directly into the XCode project, it is better to embed the SQL source file into the project and then setup a compile rule in XCode to generate the db file and embed it into the bundle at compile time. As he points out this has a particular advantage related to source code control. He provides an example of how to do this here.

Step 4: Link to the SQLite Library

Finally you are ready to link to the library that contains all of the SQLite functions. To link to that library, from your XCode project right click the frameworks folder and select “Add->Existing Frameworks…”.

addFramework.jpg

Next, navigate to the your iPhoneSDK folder and select the usr/lib/libsqlite3.0.dylib file. (Don’t be confused by the other libsqlite*.lib files in that folder, they are all just aliases to this one.)

Xcode.jpg

You are now ready to start writing some SQLite code. (Again see the SQLiteBooks sample code for some tips on doing that.)

Update: Jonathan Wight also suggested that it is better to use the other linker flags setting in the the Build tab of the Project settings to link to the SQLite library instead of using the framework method. You can do this by adding the -lsqlite3 flag to that field as shown here:

Project “SQLiteBooks” Info.jpg

This method has the advantage of linking to the correct library no matter what platform you are targeting.

SQLite on the iPhone Nuances

  1. SQLite on the actual iPhone is much slower for some things than on the simulator. In particular the same queries that run in the blink of an eye on the simulator take several seconds to run on the actual device.
  2. If you need to write to your database, make sure you make a copy of it in a location that you can write to. See the SQLiteBooks sample code for an example of how to do this.
  3. Be aware that SQLite extensions such as Full Text Search don’t appear to be compiled into the iPhone SQLite libraries.
  4. Plan for the future! If you plan on adding a feature that relies on a certain table or field in the database make that part of your database design now. This will save you the trouble of having to write all the necessary SQL commands for versioning your database later when you release an application update.

Scriptures Update - Call for Localizers

September 26th, 2008

The Scriptures 1.0.4 for iPhone / iPod Touch is now available for download. This release contains a couple of bug fixes and new features.

What’s New

newLargeIcon.jpgOne feature that has been consistently requested is the ability to navigate between chapters. There are now buttons on the title bar that allow you to do just that. These buttons also allow you to quickly navigate between search results.

I’ve also added the ability to change font styles. Though I personally think The Scriptures look better in a serif font, a few people have asked for the ability to change to a sans-serif view. You can now make that change in the application settings.

Finally, I also added the really nice icon that Gaige Redd has contributed. I really wanted to keep the Angel Moroni theme and Gaige did a great job with it.

There were also a few bug fixes, which you can read about in detail in the changelog.

What’s Next

There are three things that I’m currently working on and hope to be done with soon:

  1. More Content - Everyone wants more content. I’m not sure what will be added when, but I can tell you that the first things I want to include are chapter headings, footnotes, and study helps.
  2. Bookmarks and Annotations - Coming very very soon. The tricky part with this isn’t the coding. It is trivial to mark spots in the scriptures, or to create a list of saved locations to navigate to. The tricky part (as with any new feature) is the UI Design. On a device like the iPhone especially it is critical to get the UI right. I’ve been working at this and I think that you will like the UI design that I’ve settled on.
  3. Localizations (aka Translations) - I have gotten so many requests for translations as well as offers for help, and this is a priority item that I want to get done soon. (More on this below)

Calling all Localizers

In the software development world implementing an application in a new language is commonly called localization rather than translation for a couple of reasons.

First of all you aren’t just translating the content, you are also converting the UI to work as expected in the locale where the new language is spoken. That means things like dates and currency should be appropriately converted.

Also, localization (especially of the UI) doesn’t just mean translating the commands word for word with a dictionary. Just as in English, every language has certain idioms and conventions that are used in technology that go beyond a simple translation. For example look at this screenshot of iTunes in its Brazilian Portugûese localization:

iTunes.jpg

Notice how the “View” menu is localized as “Visualizar” which is literally “To Visualize” rather than “Vista” which is the noun for view. Also notice how the “Store” heading is localized as “Loja” which is a direct translation for store, but that “iTunes Store” is left alone. Also, “Ringtones” is localized as “toques” which literally means the plural noun “touches”.

Why am I telling you all of this? Because I need your help. While I am fluent in English and Brazilian Portûguese because of the time I spent in Brazil, there are many other languages that I would like to do localizations for. (And even for Portûguese I don’t know all of the necessary technical conventions needed for the UI localization).

Desired Qualifications

If you would like to help, here are the qualifications:

  1. You must be a native speaker or have near native fluency in the language you want to help localize.
  2. You must have experience using software in the language you want to help with. (So you’ll know those conventions I mentioned above).
  3. You must be willing to install buggy beta software on your iPhone or iPod Touch.
  4. You must know how to find your iPhone’s Unique Device Identifier. (I need this in order to make the beta software run on your device)
  5. Previous experience as a beta tester/localizer is preferred, but not necessary.
  6. You should know how to write a good bug report.
  7. You must be willing to do this for absolutely no compensation.

The Localization Process

The localization process will basically work like this:

  • You will email me with your name, the language(s) you would like to assist with and the UDID of your iPhone or iPod Touch.
  • I will email you a list of terms from the user interface that need to be localized.
  • You will email me back a list of localizations for each of those terms in the form: “English Term: Localized Term”
  • I will make the necessary updates in the application to incorporate the localization.
  • I will send you a beta version of the software containing the localization along with instructions on how to install it.
  • You will install the beta software and test it, paying special attention to the localizations.
  • You will send me reports for any bugs that you find.
  • I will fix the bugs that are reported, create a new version of the beta software, and email it to you.
  • You will install the new beta software and test it, paying special attention to the localizations.

Once everyone is satisfied that there are no problems with the localization, the update will be submitted to the App Store for distribution.

If after reading this you are interested in helping out, you may send me an email with your name, device UDID, and the language(s) you would like to assist with. I can’t guarantee that every language will be done, nor the order that I will go in, but I will do as many as I can that the Scriptures are available for in digital form.

You may email me at: lee <dot> falin <at>gmail <dot> com

The Scriptures 1.0.4

September 21st, 2008

I just finished submitting version 1.0.4 of The Scriptures for the iPhone/iPod Touch for review. I’ll post an update when it is approved. For more information on what’s new in this version, see the changelog.

The Scriptures 1.0.1

August 12th, 2008

The Scriptures for the iPhone and iPod Touch version 1.0.1 is now in review status at the App Store. You can read about the changes here.

On App Store Reviews

One thing I’ve noticed about the reviews that the application has received is that they are all pretty favorable, which I’m grateful for. The ones that aren’t favorable (which are all one star reviews), all have a common theme. Not one of them is a review of the application itself, but of the religion that the application is designed for.

I should be used to people criticizing and mocking my religion, but what always amazes me is how members of other Christian churches feel it is their duty to expose us as some radical group of wacko impostor Christians simply because our beliefs regarding the Savior are different than their own.

This isn’t a new practice among Christians, but as illustrated in Luke chapter 9 it is one that we should all know better than to follow:

49 And John answered and said, Master, we saw one casting out devils in thy name; and we forbad him, because he followeth not with us.

50 And Jesus said unto him, Forbid him not: for he that is not against us is for us.

Apple handles these types of reviews in the App Store by providing a “Was this review helpful” feature, which other people can answer yes or no. Since by default the reviews are sorted by most helpful, these types of irrelevant reviews tend to get pushed towards the bottom.

On “Competition”

Something else I’ve noticed in the App Store reviews is a tendency for people to compare The Scriptures application which I developed to the one developed by Michael Jensen. Such comparisons between similar applications are natural, however there a few things regarding these comparisons that I feel a need to comment on.

First of all my application is not in competition with Michael’s. Compete is defined as:

verb: strive to gain or win something by defeating or establishing superiority over others who are trying to do the same

I am not striving to gain or win something, nor am I trying to defeat or establish superiority over Michael’s app. When I started writing The Scriptures, there was no LDS Scripture reader for the iPhone yet available. I wanted one, so I decided to write one. While I was writing one, Michael’s was released. It takes a bit of time to design and develop an application. (Not to mention how long it takes to get one through the App Store review process), so don’t think that I saw Michael’s app and said to myself, “Hmmm, I think I’ll write a free version to compete with this.”.

This brings me to my next point, some reviews that I have seen on both my (and recently Michael’s) app, have criticized Michael for charging money for something that many people believe should be given away for free. While I don’t charge for my application, having run a software business for some time, I can’t begrudge someone for wanting to charge money for their work. Michael has stated that he contracted with a developer to write the application. This of course costs money. We don’t know if it was an hourly rate, a one time contract, if there was a retainer fee for updates, if royalties are involved, etc.. On top of that, there is a cost involved to just getting an application in the App Store once it is written.

It isn’t fair to Michael to pass judgement on him when we don’t know the particulars of the financial details involved in his situation. We shouldn’t forget the work he did to make ReadScriptures.com available for free (which must be costing Michael some of his personal money every month just in hosting fees). Above all we should remember that Michael is a son of God with a wife and children that love him. That alone should command our respect.

</soapbox>

It has given my great joy to write this application and see people receive it favorably. In the latest release, I tried to incorporate as many suggestions from users as I could given my time constraints. I hope to add even more great features in the future, so please keep your emails coming. It’s nice to hear from users that are enjoying some feature that I worked hard to design and implement. Just to give you an idea of things to come, the next point release should include:

  • Scripture marking support.
  • Annotations (note taking).
  • Inter-chapter navigation.
  • The ability to change to a sans-serif type font
  • (Hopefully) footnotes

If I am able to include more content, I will. As I have already told many of you regarding this, some of those items that I want to include are under copyright from the church and I can’t legally put them into an application for distribution without their permission, hopefully however, that will be resolved soon.

Finally some people have asked if they could donate to support this effort. The answer is thanks, but no. The Scriptures are and will remain free. As I mentioned on the project page, if you like the application so much that you want to donate something, instead of sending me money, make a donation to the Church’s Perpetual Education Fund to help the next generation of application developers (among other careers).

Thanks again for everyone’s support, as always Please send all bug reports / feature requests to me via email:

lee <dot> falin <at>gmail <dot> com

LDS Scriptures for the iPhone/iPod Touch

August 5th, 2008

I have just uploaded my first iPhone/iPod Touch to the App Store!

IMG_0001.PNGThe Scriptures for the iPhone/iPod Touch

It is currently pending approval. I’ll post a link to its appstore page when it comes available.

In the mean time, head over to its project page to check it out.

Developing for the iPhone is an interesting process, there is a lot that is different from developing applications for the Mac, not just in terms of the standard controls, but also in terms of how you think about the project design, and program flow.

If the NDA ever gets lifted on the iPhone SDK, I’ll talk more about those differences.

Update: The Scriptures is now available for download.