IPhone application content update

    Many mobile applications show the user content from the server, and this content can be displayed online and offline. Working online is trivial - with a certain UI event, the application reads data from the network and shows it to the user. Work offline can be much more interesting - the ability to work with documents in the subway, etc. But working outside the network also brings problems: now you need to synchronize data and this process should not block the user interface.

    Elements in the source code

    - access to network resources
    - xml processing
    - access to the file system
    - work with streams

    Application requirements

    The application should show text files from the server in offline mode. At each start, synchronization occurs. At the same time, the update process should not block the user’s work with the interface. The update process itself consists of two steps:
    1. Reading a list of files from the server
    2. Downloading missing files

    Code design

    To manage the entire process, we will create an UpdateManager class that will manage the Updaters objects. At the moment, we need two "Updater": one for reading the list of files and the second for working with files. We will define a single facade for them, which will expand the system in the future. This facade will have at least one method - start - which will be called by UpdateManager for each Updater in turn.

    We know in advance that we will use an asynchronous connection to access the network. This forces us to clearly continue the work of UpdateManager after the completion of each Updater'a.
    We will declare two protocols:

    @protocol UpdateManagerProtocol - (void) next;

    @protocol UpdaterProtocol - (void) startUpdate: (id) manager;

    UpdateManagerProtocol declares one method that is called by each Updater when it completes.

    Our classes look like this:
    Class diagram

    All Updater's work the same way:
    Seq diagram

    XMLListUpdater performs the steps:
    1. Reads the xml file from the server to the buffer
    2. Parses xml
    3. Adds each file to the queue

    FileUpdater performs the steps:
    1. Get the next file from the queue
    2. Checks if the file already exists on disk
    3. Downloads the file
    4. Repeats the process if the queue is not empty


    To start, we’ll write the code without mentioning the threads.

    UpdateManager.h declares one static method to start the whole process. In the constructor (init) of the instance, all Updaters are created, added to the queue, and called one after another.

    Since each Updater reads data from the network, the general code can be moved to a separate class - NetworkClient. It implements UpdaterProtocol together with a method to start an asynchronous connection (startNetworkCall).

    The first Updater is XMLFileUpdater. At startup, it reads xml into memory from a previously known address. Upon completion, XMLListUpdater creates an xml parser for data processing. Each file from the list is added to the queue for processing by the following Updater.

    The second step in updating FilesUpdater content is to read the queue and download each missing file.

    Now we can start the UpdateManager process, when loading the main view - and the application synchronizes the content.

    View contains only one button, without any action. When updating content, the interface will be blocked and pressing the button will reveal this. Later we will get rid of blocking by adding a new thread.

    Adding a separate stream

    Since we already have all the code for working with data, it remains for us to start a separate thread and perform an update in it.
    Add a new method to UpdateManager - startInThread. With simple steps:
    1. Create an NSAutoReleasePool
    2. Start the update process
    3. Run RunLoop
    4. Free the pool

    NSAutoRelease must be created in each new thread for automatic memory management. Otherwise, you will get a lot of errors in the console.

    RunLoop is a more interesting thing. If you comment out RunLoop and start the application, you will see a message about the beginning of the network connection, but other events - such as receiving data from the network, terminating the connection - will not occur. The problem is the early termination of the thread - which ends when you exit the "startInThread" method. Therefore, we run RunLoop so that the thread remains active.

    Now the initialization of UpdateManager can be moved to main.m.

    Source Code Notes

    UpdateManager.h contains compilation directives - WORK_IN_SEPARATE_THREAD. If it is set to zero, then a new thread will not be created and the UI will be blocked. At one, the update will take place in a separate thread.

    Source code: SF.net

    Andrew Romanenco
    April, 2010

    Also popular now: