Sharing Information Between Views

September 23rd, 2011

One of the most common questions in the Getting Started section of Apple’s Developer Forums is, “How do I edit information in one view and update another using it?” Sometimes it’s expressed instead as how to compare or save information in different views but it’s really the same question. There are two answers: the expedient one and the good one. Before I get to either of those, however, I’d like to set up a sample situation.

The Problem:
I’m going to work with a project that’s created using the standard iPhone Tab Bar Application template, using Xcode 4.0.2. It defaults to having two view controllers and my plan is to have the first one be a data display screen while the second is a data editing screen. (Note: My latest build of this works on Xcode 4.5.2 and iOS 6.0 with conversion to ARC.)

To prepare for this, I edit the supplied .xib files so that FirstView.xib has only a UILabel element inside its view and SecondView.xib has only a UITextField element inside its view. I then modify the related code files for the view controllers to define and synthesize properties that match the label and the text field. Finally, within the .xib files, I make the connections between the File’s Owner properties that were just created in code and the visual elements.

Usually, this is the state the person has reached when they ask the question. If they haven’t made it this far, the questions are more likely to be about how to use Interface Builder.

The Expedient Solution:
This addresses the problem as a lack of understanding about objects. The point that’s being missed is that objects need to have references to other objects while the program is running in order to communicate. Since I want my view controllers to communicate with each other, one of them must have a reference to the other. I could have my editor update the display whenever data changed but, for a variety of reasons, I prefer the idea of the display being in control of its own content.

Within the code for the FirstViewController, I create a property that references a SecondViewController object and synthesize it. Instances of both controllers exist inside MainWindow.xib so I connect the new property of the first controller to the SecondViewController instance.

The last step is to write code so that the FirstViewController can obtain the most recent information whenever it is about to be displayed…and that is now trivial.

Relevant controller code:

//  SecondViewController.h

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController <UITextFieldDelegate> {
}

@property (nonatomic, retain) IBOutlet UITextField *dataEditor;

– (NSString *)editedText;

@end

// SecondViewController.m

#import “SecondViewController.h”

@implementation SecondViewController

@synthesize dataEditor;

– (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

– (NSString *)editedText {
    if (dataEditor == nil) {
        return @”Not initialized”;
    }
    return dataEditor.text;
}

– (void)dealloc {
    [dataEditor release];
    [super dealloc];
}

@end

// FirstViewController.h

#import <UIKit/UIKit.h>

@class SecondViewController;

@interface FirstViewController : UIViewController {
}

@property (nonatomic, retain) IBOutlet UILabel *dataDisplay;
@property (nonatomic, retain) IBOutlet SecondViewController *dataSource;

@end

// FirstViewController.m

#import “FirstViewController.h”
#import “SecondViewController.h”

@implementation FirstViewController

@synthesize dataDisplay, dataSource;

– (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    dataDisplay.text = [dataSource editedText];
}

– (void)dealloc {
    [dataDisplay release];
    [dataSource release];
    [super dealloc];
}

@end

The Better Solution:
Here, in addition to thinking about objects, I use a simple implementation of the Model-View-Controller (MVC) object pattern. In the previous solution, the second controller acted as the data model for the application. Programs become much easier to expand and modify when that role is given to objects specifically created for the purpose.

I create a new class called SharedModel and make it a subclass of NSObject. I create a property for it that will hold a reference to a NSString object. (In a real application, the SharedModel could be expanded to serve any amount of data, even remote sites.)

I remove all references to SecondViewController from the first controller and insert properties called ‘dataSource’, that each specify a reference to the SharedModel, into both controllers.

The following is not necessarily the best way to handle the creation of the SharedModel but, for illustration purposes, it works. In MainWindow.xib, I add a NSObject and set its class to SharedModel. I then connect the dataSource property of each view controller to the new SharedModel object in the .xib file.

The last steps are: to add one line of code in the second controller that updates the SharedModel when editing ends, to remove the code from the second controller that reported the edited text to the caller, and to modify the update line in FirstViewController so that it uses the data model instead of the second controller directly.

Relevant controller and model code:

// SharedModel.h

#import <Foundation/Foundation.h>

@interface SharedModel : NSObject {
}

@property (nonatomic, retain) NSString *editedText;

@end

// SharedModel.m

#import “SharedModel.h”

@implementation SharedModel

@synthesize editedText;

– (id)init {
    self = [super init];
    if (self) {
        self.editedText = @”Not updated”;
    }
    return self;
}

– (void)dealloc {
    [editedText release];
    [super dealloc];
}

@end

// SecondViewController.h

#import <UIKit/UIKit.h>

@class SharedModel;

@interface SecondViewController : UIViewController {
}

@property (nonatomic, retain) IBOutlet UITextField *dataEditor;
@property (nonatomic, retain) IBOutlet SharedModel *dataSource;

@end

// SecondViewController.m
#import “SecondViewController.h”
#import “SharedModel.h”

@implementation SecondViewController

@synthesize dataEditor, dataSource;

– (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    dataSource.editedText = textField.text;
    return YES;
}

– (void)dealloc{
    [dataSource release];
    [dataEditor release];
    [super dealloc];
}

@end

// FirstViewController.h

#import <UIKit/UIKit.h>

@class SharedModel;

@interface FirstViewController : UIViewController {
}

@property (nonatomic, retain) IBOutlet UILabel *dataDisplay;
@property (nonatomic, retain) IBOutlet SharedModel *dataSource;

@end

// FirstViewController.m

#import “FirstViewController.h”
#import “SharedModel.h”

@implementation FirstViewController

@synthesize dataDisplay, dataSource;

– (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    dataDisplay.text = dataSource.editedText;
}

– (void)dealloc {
    [dataDisplay release];
    [dataSource release];
    [super dealloc];
}

@end

Timely: Market Research

March 8th, 2011

For much of my programming career I’ve worked for small companies that were in the process of creating their first commercial software product. Usually, the impetus for creating a product was someone’s idea of what would cause a lot of people to spend money. It was never something that the idea person would spend his or her own money on, and the companies in question weren’t rich or mature enough to actually do research that would demonstrate whether or not the financial assumptions were true.

The immediate result of this mode of operation was requirements that could change at a moment’s notice whenever someone with political clout claimed to know what the mythical customer would want. The longer term results included a series of technical successes that did poorly when they were presented to a market that didn’t care and, in one case, entertaining fluctuations in pricing that ranged — as I remember it — between $0.00 and $1400.00, depending on whether “Software as a Service” was in vogue that day.

This brings me to an iPad program called Timely that I’ve recently uploaded to Apple for approval. I’ve specified, designed, and written it myself…just as I have many other programs in my life. Although I’ve asked some people for their opinions about features, what it contains in its first version is what I need.

See, when I’m not writing code, I’m fairly seriously caught up in my hobby of songwriting, singing, and guitar playing within the filk community.

Timely lets me store and display songs in a variety of formats and then accumulate them into overlapping set lists. It estimates set length as I change my mind while organizing one. It should let me stop carrying many pounds of paper when I go off to conventions, practices, and monthly filk circles. It displays songs by automatically scrolling them so that I don’t have to turn pages or compress song notation into a maximum of two pages. It organizes songs alphabetically and lets me make reference notes about them. It optionally plays a note when a song starts for times when I need a cue.

It’s the program I want and will evolve as my needs evolve and as I see more things I’d like it to do.

It has not been written for customers which may or may not exist and which might number between zero and seven billion. I wish I could have written it for all the people who might find it useful enough to buy it. That would have produced the best focus group, but it’s impossible to do and impractical to simulate. Instead, Timely has been written for one customer which, in my experience, is the second-best number.

Link Spam Reporting

December 13th, 2010

Like anyone operating a site that allows user comments, this blog is subject to spam entries. These are context-free blurbs that contain links to other sites for the purpose of inflating search ranking. Welcome to the world of “Search Engine Optimization”. Luckily, there’s a WordPress plug-in called Akismet that does an excellent job of identifying junk and putting it into quarantine.

These comments are likely being posted using compromised computers and without the explicit knowledge of the owner of the promoted site. When I find one that appears to be connected to a legitimate business (as opposed to the usual porn, plagiarism, and gambling sites), I’ve started contacting the site — if possible — to make sure they’re aware of what’s being done on their behalf. I also intend to update this post to keep track of any progress I make in my attempts at education. (I debated with myself about quietly ignoring them and thereby denying them extra attention, but decided I’d rather make their existence public.) Signs of reform or intransigence will be noted.

  • 2010.12.13 – UGG is an Australian boot seller that seems to attract two kinds of vermin: producers of counterfeit products and ‘affiliates’. The spammed domain is adirondacktallugg (com). I’ve contacted them in case they’re a legitimate reseller with an affiliate problem. Checking their site doesn’t make me optimistic, however; too many of the pages are templates with no content.
  • 2010.12.15 – A Wikipedia link to someone named Harold Perrineau. (OK, that’s weird.)
  • 2010.12.15 – An unofficial site, nominally set up to discuss Sears Cards Credit Cards: searscardcomm (com). There’s no contact information on the site.
  • 2010.12.16 – A blog about motorcycle fairings called cheap-motorcycle-farings (net). Yes, they spelled their domain name wrong.
  • 2010.12.23 – Another from the motorcycle people, but this time it’s a different domain, with improved spelling: motorcycle-fairings (info).
  • 2010.12.28 – A hosting company, possibly fake considering that many of its links lead to internet marketing garbage: imcashsaver (com).
  • 2010.12.28 – A seller of — let’s assume counterfeit — Nike running shoes: airmaxshoesmart (com).
  • 2010.12.28 – A site promoting a flash game: crush-the-castle (com).
  • 2010.12.29 – Green Bay Packer jerseys: packerjerseyshop (com).

WordPress for iOS

November 9th, 2010

This is being created using a WordPress application designed specifically for the iPad.
The main benefit seems to be the ability to store drafts locally. Less useful is the
text editor that doesn’t wrap lines and the viewer that doesn’t interpret HTML.

On the other hand, I’ve only been using it for five minutes…we’ll see how it goes.

(And now I’ve tried saving and re-editing a draft.)

A Transparent Interface

June 11th, 2010

I bought an iPad a few days ago.  Yes, it’s sleek and hot and hyped, but mostly it’s easy.

Apple has always been good about providing an intuitive user interface and this time they’ve gone a step farther.  The learning curve here is so gentle that the idea of a user interface almost disappears.  It’s like discussing the user interface of a pot handle; generally, you see it and immediately do what’s necessary to get the effect you need.

As I collect information on how to write applications for the iPad, I see suggestions about making the user’s view of those apps match the iPad style.  It’s an important point.  This isn’t a Mac and it isn’t an iPhone either.  It’s a unique device that deserves its own special interface style for a program that runs on it — a very easy one.

An Electronic Filkbook

February 2nd, 2010

With the recent announcement of Apple’s iPad, I’m once again thinking about the fact that many people in the filk community use a laptop computer as a songbook. This appears to work fairly well for those who don’t play an instrument (or who have a third hand to look after scrolling and page-turning while the song is in progress). Others might like to make the transition to an electronic book and sometimes mention the idea of a foot-operated device that would be used to page through material while playing. For most songs on most devices, showing everything at once isn’t feasible in a readable font.

Being a programmer, I think, “Can I do something about this in software?

Here’s what I see as basic requirements. Feel free to add other suggestions in comments. The purpose of the program is to display a song file in such a way that the correct portion of its content is viewable as appropriate to the length of the song, the elapsed time since the song started, and the size of the application window.

  • the user will specify the song’s file, its length in minutes and seconds, and scrolling options
  • the program will automatically scroll the song display proportional to elapsed time
  • assuming a reasonable size of application window, the program should be well-behaved for approximate song lengths
  • supported file formats should be at least plain text and RTF
  • user control changes (e.g. manual scrolling) will override automatic functioning
  • the program will save the meta-information related to each song file and use it by default in subsequent performances
  • the program will support the concept of a Set List, which references a number of songs
  • songs in a Set List will be activated by manual use of a ‘next’ control

I realize that there is software available to turn a computer into a teleprompter, but what I’ve seen of it makes display assumptions and doesn’t take into account the repeat use of content in different contexts.

Something Has To Be First

September 25th, 2009

The intent of this site is to present analysis of various topics within the business and practice of software development.  My interests tend toward the technical rather than the theoretical except for those times when the promotion of buzzwords interferes with the use of technology.