<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>RaddOnline Web Developers Blog Full Text RSS Feed</title>
    <link>http://www.raddonline.com/full-text-rss/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>RaddOnline Full Text RSS Feed</description>
    
    
        <item>
          <title>Ruby on Rails: Using Exchange Web Services from a Rails App</title>
          <description>&lt;p&gt;&lt;acronym title=&quot;Exchange Web Services&quot;&gt;EWS&lt;/acronym&gt; is a &lt;acronym title=&quot;Simple Object Access Protocol&quot;&gt;SOAP&lt;/acronym&gt; service for interacting with data stored in an Exchange server. You can use it to get a list of events from the calendar, or a list of emails. You can also create or delete items in exchange. In my app, I wanted to create events on an Exchange calendar when a user was assigned to a scheduled task. I also wanted to delete events, and possibly create new ones, if the user was removed or re-assigned.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll be demonstrating how to use cURL to consume the &lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt; services. I&amp;#8217;ve created a very simple rails project as a sample which is available at GitHub. &lt;a href=&quot;http://github.com/timstephenson/EWS-Connect&quot;&gt;&lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt;-Connect&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;There are also a couple of good gems that you can try:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/zenchild/Viewpoint&quot;&gt;Viewpoint&lt;/a&gt; Uses Soap4r and HTTPClient, is a pretty complete client access library for Exchange Web
Services in Ruby. Dan Wanek, the author, is very responsive and helpful.&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://github.com/jrun/ews-api&quot;&gt;ews-api&lt;/a&gt; Favors Handsoap over Soap4r.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I didn&amp;#8217;t user either gem because both gems depend on HTTPClient and RubyNTLM. I ran into a problem with authentication on the server. I could authenticate using cURL, but never succeeded with HTTPClient. I know that &lt;span class=&quot;caps&quot;&gt;NTLM&lt;/span&gt; is supported, and couldn&amp;#8217;t find anything specifically wrong to fix, so I decided to use cURL for my implementation.&lt;/p&gt;


	&lt;h3&gt;Creating the Connection With cURL&lt;/h3&gt;


	&lt;p&gt;This part is easy. There is a single cURL command needed, so I created a very simple wrapper class called ExchangeConnection.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;class ExchangeConnection

  # This could easily have been included in the ExchangeService class.
  # Having a separate connection class made it easy to mock the connection
  # in the exchange service tests. 

  def initialize(user, password, endpoint)
    @user, @password, @endpoint = user, password, endpoint
  end

  # Uses cURL to connect to the EWS server.
  # Passes the Soap XML document as the data.
  def connect(xml_doc)
    wsdl = `curl -u #{@user}:#{@password} -L #{@endpoint} -d &quot;#{xml_doc.write}&quot; -H &quot;Content-Type:text/xml&quot; --ntlm` 
  end

end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The connect method takes an &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; document and uses the -d option to post the document as the data to &lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt;. The user, password and endpoint variables are initialized when the instance is created. The endpoint is the url to the &lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt; server. The contents of the response are returned after the connection.&lt;/p&gt;


	&lt;p&gt;There is a good gem that you can also try for libcurl. See &lt;a href=&quot;http://github.com/taf2/curb&quot;&gt;curb&lt;/a&gt; on GitHub.&lt;/p&gt;


	&lt;h3&gt;Making a Request&lt;/h3&gt;


	&lt;p&gt;There are two tasks to create an item in &lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt;.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Format the &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; to make the request. &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa564690.aspx&quot;&gt;Here&amp;#8217;s the definition from &lt;span class=&quot;caps&quot;&gt;MSDN&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Parse the response, and if it succeeds, get the item id as a reference so that it can be deleted in the future.&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;def create_event_in_ews(event, target_mailbox = nil, attendee_addresses = [])
    connection = ExchangeConnection.new(APP_CONFIG[:ews_user_name], APP_CONFIG[:ews_user_password], APP_CONFIG[:ews_endpoint])
    begin
      response_doc = REXML::Document.new(connection.connect(create_calendar_item_xml(event, target_mailbox, attendee_addresses)))
      status = REXML::XPath.first(response_doc, '//m:CreateItemResponseMessage').attribute('ResponseClass')
    rescue =&amp;gt; e
      @errors &amp;lt;&amp;lt; &quot;Uh-oh, there was an XML exception: #{e}.&quot; 
      return false
    end

    if status.to_s != &quot;Success&quot; 
      response_code = REXML::XPath.first(response_doc, &quot;//m:ResponseCode&quot;).text
      message = REXML::XPath.first(response_doc, &quot;//m:MessageText&quot;).text
      @errors &amp;lt;&amp;lt; &quot;EWS appointment creation failed. Status: #{status.to_s}. Response code: #{response_code}. #{message}&quot; 
      return false
    end

    calendar_ids = REXML::XPath.match(response_doc, '//t:ItemId')
    calendar_ids.each { |item|
      @appointment_id = item.attribute(&quot;Id&quot;).to_s
    }
    return true
  end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This method uses &lt;span class=&quot;caps&quot;&gt;REXML&lt;/span&gt; to create an &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; document from the response. This line does all the work:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;response_doc = REXML::Document.new(connection.connect(create_calendar_item_xml(event, target_mailbox, attendee_addresses)))&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;After the response is returned, it&amp;#8217;s just a matter of parsing it for the important bits of information. If all goes well, the id returned from the server is stored in the variable @appointment_id. Else, an error is stored.&lt;/p&gt;


	&lt;h3&gt;Formatting the &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; for the Request&lt;/h3&gt;


	&lt;p&gt;Formatting the &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; for the request is a little more interesting. I&amp;#8217;ve used a helper from the Ruby Cookbook so that the code that creates the doc could be nested in the same way as the &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; file itself. This goes into the config/initializers folder.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;class REXML::Element
  # Helper to create xml docs with a nested syntax.
  def with_element(*args)
    e = add_element(*args)
    yield e if block_given?
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The code to create the &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; document looks like this.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# Takes an event and creates the XML to create a calendar item.
  # Soap schema information can be found at:
  # http://msdn.microsoft.com/en-us/library/aa564690.aspx
  # Params:
  # * event - Should have a name, location, description and start and end times.
  # * target_mailbox - The email address for the calendar the event should go to. If nil, it will go on the calendar of the user the app logs in with.
  # * attendees - An array of email addresses that will be added as attendees.
  def create_calendar_item_xml(event, target_mailbox = nil, attendee_addresses = [])

    doc = REXML::Document.new
    doc.with_element('soap:Envelope', envelope_data) do |envelope|
      envelope.with_element('soap:Body') do |body|
        body.with_element('CreateItem', create_item_data(attendee_addresses.length &amp;gt; 0)) do |create_item|

          create_item.with_element('SavedItemFolderId') do |saved_item_folder_id|
            # Will add the event to the calendar of the user that the app logs in as.
            if target_mailbox.blank?
              saved_item_folder_id.add_element('t:DistinguishedFolderId', {'Id' =&amp;gt; &quot;calendar&quot;})
            else

              # This adds an event to to the calendar specified by the mailbox.
              # Schema info: http://msdn.microsoft.com/en-us/library/aa580808.aspx
              # In order to succeed, the user who owns the target mail box must grant
              # permission to the user that the app logs in as.
              saved_item_folder_id.with_element('t:DistinguishedFolderId', xmlns_types.merge({'Id' =&amp;gt; &quot;calendar&quot;})) do |distinguished_folder_id|
                distinguished_folder_id.with_element(&quot;Mailbox&quot;) do |mailbox|
                  mailbox.with_element(&quot;EmailAddress&quot;) do |email|
                    email.add_text(target_mailbox)
                  end
                end
              end # end distinguished folder id
            end #if target_mailbox.blank?
          end

          # The items block in the XML
          create_item.with_element('Items') do |items|

              items.with_element(&quot;t:CalendarItem&quot;, xmlns_types) do |t_calendar_item|
                subject = t_calendar_item.add_element(&quot;Subject&quot;)
                subject.add_text(event.name.blank? ? &quot;Rails EWS Test&quot; : event.name)

                body = t_calendar_item.add_element(&quot;Body&quot;, {'BodyType' =&amp;gt; &quot;Text&quot;})
                body.add_text(event.description)

                reminder_is_set = t_calendar_item.add_element(&quot;ReminderIsSet&quot;)
                reminder_is_set.add_text(&quot;true&quot;)

                reminder_minutes_before_start =  t_calendar_item.add_element(&quot;ReminderMinutesBeforeStart&quot;)
                reminder_minutes_before_start.add_text(&quot;60&quot;)

                event_start =  t_calendar_item.add_element(&quot;Start&quot;)
                event_start.add_text(event.start_datetime.strftime(&quot;%Y-%m-%dT%H:%M:%S&quot;))

                event_end = t_calendar_item.add_element(&quot;End&quot;)
                event_end.add_text(event.end_datetime.strftime(&quot;%Y-%m-%dT%H:%M:%S&quot;))

                all_day = t_calendar_item.add_element(&quot;IsAllDayEvent&quot;)
                all_day.add_text(event.all_day?.to_s)

                status = t_calendar_item.add_element(&quot;LegacyFreeBusyStatus&quot;)
                # There are several options that can be used for the status. 
                # * Free
                # * Busy
                # * OOF - Out of office - etc.
                status.add_text(&quot;Busy&quot;)

                location = t_calendar_item.add_element(&quot;Location&quot;)
                location.add_text(event.location) unless event.location.blank?
                # If you have attendees, you would add them here.
                # If the SendToNone option is seleceted, then it seems to ignore attendees anyway.
                t_calendar_item.with_element(&quot;RequiredAttendees&quot;) do |attendees|
                  attendee_addresses.each do |email_address|
                    attendees.with_element(&quot;Attendee&quot;) do |attendee|
                      attendee.with_element(&quot;Mailbox&quot;) do |mailbox|
                        mailbox.with_element(&quot;EmailAddress&quot;) do |email|
                          email.add_text(email_address)
                        end
                      end
                    end
                  end # attendee_address.each
                end # end of attendees
              end # end of calendar item

          end # items
        end # body
      end # envelope
    end # doc
    return doc
  end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This looks scarier than it is. I&amp;#8217;m using &lt;span class=&quot;caps&quot;&gt;REXML&lt;/span&gt; to create an &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; document formatted to the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa564690.aspx&quot;&gt;specifications&lt;/a&gt; provided by Microsoft. There are two interesting things in this method regarding mailboxes.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;The SavedItemFolderId can be left alone to add the event to the calendar of the user that the application logged in as. Or you can target a specific mailbox. In this example, the target_mailbox defaults to nil. The default behavior is to use the application&amp;#8217;s user. Just pass an email address if you want it to go into another user&amp;#8217;s calendar. The only caveat is that the target person must grant permission to the application&amp;#8217;s user before events can be placed on the target user&amp;#8217;s calendar. &lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt; will return an error message that the mailbox can not be found if permission has not been granted. See this section of code: &lt;code&gt;create_item.with_element('SavedItemFolderId')&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;You can include required attendees and each of them will get an invitation to the event. See: &lt;code&gt;t_calendar_item.with_element(&quot;RequiredAttendees&quot;)&lt;/code&gt; If you pass an array of email addresses in the &amp;#8220;attendee_addresses&amp;#8221; parameter, each of them will be added as RequiredAttendees, and each will receive an invitation.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Take a look at the sample application to see all of the details, and how to delete events using &lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt;. You can download the complete sample and browse all the code at GitHub. &lt;a href=&quot;http://github.com/timstephenson/EWS-Connect&quot;&gt;&lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt;-Connect&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://github.com/timstephenson/EWS-Connect/blob/master/app/models/exchange_service.rb&quot;&gt;Here&amp;#8217;s the ExchangeService class.&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;You can also run the tests without an &lt;span class=&quot;caps&quot;&gt;EWS&lt;/span&gt; server. The connections are all mocked out. If you&amp;#8217;d like to run tests against a real server, just modify one of the tests and pass the correct credentials.&lt;/p&gt;</description>
          <pubDate>Tue, 23 Mar 2010 23:20:59 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/ruby-on-rails-using-exchange-web-services-from-a-rails-app/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/ruby-on-rails-using-exchange-web-services-from-a-rails-app/</link>
        </item>
    
        <item>
          <title>iPhone SDK: Testing Network Reachability</title>
          <description>&lt;h2&gt;Check Network Resources Before Use&lt;/h2&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/93/reachability-alert.jpg&quot; style=&quot;float: right; margin: 0px 0px 20px 20px;&quot; alt='reachability-alert' /&gt;
Using Facebook-connect for iPhone &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; to post stories to Facebook is a great feature to add to your iPhone application. But what happens if the user has no access to the network? If you don&amp;#8217;t check the network, the answer is nothing. This leads to user confusion, and it will prevent your app from being approved for the App Store.&lt;/p&gt;


	&lt;p&gt;So, how do you check? Apple provided a sample application called Reachability which provides the answer. I&amp;#8217;ll demonstrate here. In several blog posts people felt that the Reachability sample was overkill for their needs. If you agree, here&amp;#8217;s a link to a recipe from &lt;a href=&quot;http://my.safaribooksonline.com/9780321591180/ch10lev1sec3&quot;&gt;The iPhone Developer&amp;#8217;s Cookbook&lt;/a&gt; that provides an alternate solution. Even if you don&amp;#8217;t plan on using it, I recommend reading through the code in the Reachability example.&lt;/p&gt;


	&lt;h3&gt;Project Setup&lt;/h3&gt;


	&lt;p&gt;In an earlier post I used the Facebook-Connect for iPhone &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; to post stories to Facebook. I&amp;#8217;ll use the same project to demonstrate how to check that Facebook is reachable. Here&amp;#8217;s the project with the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Keys and Template Bundle IDs removed. &lt;a href=&quot;/assets/64/fbconnect-iphone.zip&quot;&gt;fbconnect-iphone.zip&lt;/a&gt; I&amp;#8217;ll include a link to the final project at the end.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://developer.apple.com/iphone/library/samplecode/Reachability/index.html&quot;&gt;Download&lt;/a&gt; the Reachability project too. I&amp;#8217;ll be importing a class from it to check the network connection status.&lt;/p&gt;


	&lt;h3&gt;Adding the SystemConfiguration Framework&lt;/h3&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/92/sysconfig.jpg&quot; width=&quot;400px&quot; alt='sysconfig' /&gt;&lt;/p&gt;


	&lt;p&gt;The reachability class uses the SystemConiguration Framework to check network reachability. Adding the framework to the project is easy.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Open Connect.xcodeproj if you haven&amp;#8217;t already.&lt;/li&gt;
		&lt;li&gt;In the Groups &amp;#38; Files area, control click on the Frameworks folder and select Add =&amp;gt; Existing Frameworks.&lt;/li&gt;
		&lt;li&gt;Look in the Frameworks folder for the SystemConfiguration.framework folder and select it.&lt;/li&gt;
		&lt;li&gt;Click Add to add the framework to your project.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;Add the Reachability Class&lt;/h3&gt;


	&lt;p&gt;Now add the Reachability Class from Apple&amp;#8217;s sample.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Control click on the Source folder in the project and select Add =&amp;gt; Existing Files.&lt;/li&gt;
		&lt;li&gt;Navigate to the Reachability project, click Classes, and select the files: Reachability.h and Reachability.m.&lt;/li&gt;
		&lt;li&gt;Click Add, then select Copy items into destination group&amp;#8217;s folder (if needed)&lt;/li&gt;
		&lt;li&gt;Click Add again.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;Using the Reachability Class&lt;/h3&gt;


	&lt;p&gt;Now that the framework and class have been added to the project, put them to work in the code. Create a variable to track the internet connection status, and two methods in the SessionViewController.h file.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Open the SessionViewController.h file and import the Reachability class: &lt;pre&gt;&lt;code&gt;#import &quot;Reachability.h&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Add a variable to track the status: &lt;pre&gt;&lt;code&gt;NetworkStatus internetConnectionStatus;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Add a property to hold the network status: &lt;pre&gt;&lt;code&gt;@property NetworkStatus internetConnectionStatus;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Add these two methods: &lt;pre&gt;&lt;code&gt;- (void)reachabilityChanged:(NSNotification *)note;
- (void)updateStatus;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;At this point, the SessionViewController interface should look like this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &quot;FBConnect/FBConnect.h&quot; 
#import &quot;PermissionStatus.h&quot; 
#import &quot;Reachability.h&quot; 

@class FBSession;

@interface SessionViewController : UIViewController
    &amp;lt;FBDialogDelegate, FBSessionDelegate, FBRequestDelegate, PermissionStatusDelegate&amp;gt; {
        IBOutlet UILabel* _label;
        IBOutlet UIButton* _permissionButton;
        IBOutlet UIButton* _feedButton;
        IBOutlet FBLoginButton* _loginButton;
        FBSession* _session;
        PermissionStatus *permissionStatusForUser;
        NetworkStatus internetConnectionStatus;
}

@property(nonatomic,readonly) UILabel* label;
@property (nonatomic, retain) PermissionStatus *permissionStatusForUser;
@property NetworkStatus internetConnectionStatus;

- (void)askPermission:(id)target;
- (void)publishFeed:(id)target;
- (void)reachabilityChanged:(NSNotification *)note;
- (void)updateStatus;

@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Finally, the implementation.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Open SessionViewController.m.&lt;/li&gt;
		&lt;li&gt;Sysnthesize the internetConnectionStatus variable: &lt;pre&gt;&lt;code&gt;@synthesize internetConnectionStatus;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Define a string for the host name of the resource: &lt;pre&gt;&lt;code&gt;#define kHostName @&quot;www.facebook.com&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Make the viewDidLoad method look like this: &lt;pre&gt;&lt;code&gt;- (void)viewDidLoad {
    //Use the Reachability class to determine if the internet can be reached.
    [[Reachability sharedReachability] setHostName:kHostName];
    //Set Reachability class to notifiy app when the network status changes.
    [[Reachability sharedReachability] setNetworkStatusNotificationsEnabled:YES];
    //Set a method to be called when a notification is sent.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:@&quot;kNetworkReachabilityChangedNotification&quot; object:nil];
        [self updateStatus];
    [_session resume];
    _loginButton.style = FBLoginButtonStyleWide;
}&lt;/code&gt;&lt;/pre&gt; I want to receive notifications if the network status changes, so I used the setNetworkStatusNotificationsEnabled:YES method. However, I found that the reachabilityChanged method wasn&amp;#8217;t called when the network status changed. I&amp;#8217;ll refactor later to fix the problem.&lt;/li&gt;
		&lt;li&gt;Implement the new methods:&lt;pre&gt;&lt;code&gt;- (void)reachabilityChanged:(NSNotification *)note {
    [self updateStatus];
}

- (void)updateStatus
{
    // Query the SystemConfiguration framework for the state of the device's network connections.
    self.internetConnectionStatus    = [[Reachability sharedReachability] internetConnectionStatus];
    if (self.internetConnectionStatus == NotReachable) {
        //show an alert to let the user know that they can't connect...
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@&quot;Network Status&quot; message:@&quot;Sorry, our network guro determined that the network is not available. Please try again later.&quot; delegate:self cancelButtonTitle:nil otherButtonTitles:@&quot;OK&quot;, nil];
        [alert show];
    }  else {
        // If the network is reachable, make sure the login button is enabled.
        _loginButton.enabled = YES;
    }
}&lt;/code&gt;&lt;/pre&gt; To update the user of the status, I display an alert with a message. When status notifications are sent later, either enable the login button or display the alert.&lt;/li&gt;
		&lt;li&gt;Add the alert delegate method: &lt;pre&gt;&lt;code&gt;#pragma mark AlertView delegate methods
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    _loginButton.enabled = NO;
    [alertView release];
}&lt;/code&gt;&lt;/pre&gt; If the network isn&amp;#8217;t available, disable the loginButton. In this app nothing can be done without a connection, so additional information would be in order.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;To test the application on the simulator, go to Network Preferences and disable your network connections. While disabled, the alert will be displayed. To test on an iPhone, put the device in Airplane mode. On an iPod, turn off the WiFi connection. I also tested on my device by walking to places where there is no Edge or WiFi network. In my tests, the reachabilityChanged method did not get called. Thanks to Shashi Prabhakar for giving me a clue about how to get it working, see his comment below.&lt;/p&gt;


	&lt;h3&gt;Refactoring to Receive Reachability Changed Notifications&lt;/h3&gt;


	&lt;p&gt;To get the change notifications I had to make several small changes. My initial observations when checking the remoteHostStatus instead of the internetConnectionStatus:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;The reachabilityChanged method was being called.&lt;/li&gt;
		&lt;li&gt;I noticed that when first initialized the remoteHostStatus is always NotReachable. &lt;/li&gt;
		&lt;li&gt;The internetConnectionStatus returns a positive result before the remoteHostStatus.&lt;/li&gt;
		&lt;li&gt;Because I am using an alert, sometimes the alert would be displayed twice or not at all when using one status or the other.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;As a result, I changed the code to track both the remoteHostStatus and the internetConnectionStatus. I also added a method to initialize the variables.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Open SessionViewController.h and add a variable and property to hold the remoteHostStatus. &lt;pre&gt;&lt;code&gt;NetworkStatus remoteHostStatus;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Also add a method to initialize the variables. &lt;pre&gt;&lt;code&gt;- (void)initStatus;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Here&amp;#8217;s the complete interface.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &quot;FBConnect/FBConnect.h&quot; 
#import &quot;PermissionStatus.h&quot; 
#import &quot;Reachability.h&quot; 

@class FBSession;

@interface SessionViewController : UIViewController
    &amp;lt;FBDialogDelegate, FBSessionDelegate, FBRequestDelegate, PermissionStatusDelegate&amp;gt; {
        IBOutlet UILabel* _label;
        IBOutlet UIButton* _permissionButton;
        IBOutlet UIButton* _feedButton;
        IBOutlet FBLoginButton* _loginButton;
        FBSession* _session;
        PermissionStatus *permissionStatusForUser;
        NetworkStatus internetConnectionStatus;
        NetworkStatus remoteHostStatus;
}

@property(nonatomic,readonly) UILabel* label;
@property (nonatomic, retain) PermissionStatus *permissionStatusForUser;
@property NetworkStatus internetConnectionStatus;
@property NetworkStatus remoteHostStatus;

- (void)askPermission:(id)target;
- (void)publishFeed:(id)target;
- (void)reachabilityChanged:(NSNotification *)note;
- (void)updateStatus;
- (void)initStatus;

@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Edit the implementation.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Open SessionViewController.m and add the initStatus method &lt;pre&gt;&lt;code&gt;-(void)initStatus {
    self.remoteHostStatus = [[Reachability sharedReachability] remoteHostStatus];
    self.internetConnectionStatus    = [[Reachability sharedReachability] internetConnectionStatus];
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Change the viewDidLoad method to call the initStatus method instead of the updateStatus method. &lt;pre&gt;&lt;code&gt;- (void)viewDidLoad {
    //Use the Reachability class to determine if the internet can be reached.
    [[Reachability sharedReachability] setHostName:kHostName];
    //Set Reachability class to notifiy app when the network status changes.
    [[Reachability sharedReachability] setNetworkStatusNotificationsEnabled:YES];
    //Set a method to be called when a notification is sent.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:@&quot;kNetworkReachabilityChangedNotification&quot; object:nil];
    [self initStatus];
    [_session resume];
    _loginButton.style = FBLoginButtonStyleWide;
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Change the updateStatus method to check both variables.&lt;pre&gt;&lt;code&gt;- (void)updateStatus
{
    // Query the SystemConfiguration framework for the state of the device's network connections.
    self.remoteHostStatus = [[Reachability sharedReachability] remoteHostStatus];
    self.internetConnectionStatus    = [[Reachability sharedReachability] internetConnectionStatus];
    NSLog(@&quot;remote status = %d, internet status = %d&quot;, self.remoteHostStatus, self.internetConnectionStatus);
    if (self.internetConnectionStatus == NotReachable &amp;#38;&amp;#38; self.remoteHostStatus == NotReachable) {
        //show an alert to let the user know that they can't connect...
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@&quot;Network Status&quot; message:@&quot;Sorry, our network guro determined that the network is not available. Please try again later.&quot; delegate:self cancelButtonTitle:nil otherButtonTitles:@&quot;OK&quot;, nil];
        [alert show];
    } else {
        // If the network is reachable, make sure the login button is enabled.
        _loginButton.enabled = YES;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;I left the log statement so that you could see how the values change as the network settings are changed. In the simulator, go to network settings and disable your connections while it is running. The reachabilityChanged method is now being called as the network status changes.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the original sample project without the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Keys and Template Bundle IDs. &lt;a href=&quot;/assets/94/fbconnect-iphone-reachable.zip&quot;&gt;fbconnect-iphone-reachable.zip&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;And the refactored sample project. &lt;a href=&quot;/assets/95/fbconnect-iphone-reachable-2.zip&quot;&gt;fbconnect-iphone-reachable-2.zip&lt;/a&gt;&lt;/p&gt;</description>
          <pubDate>Fri, 24 Apr 2009 20:36:33 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/</link>
        </item>
    
        <item>
          <title>iPhone SDK: UINavigationController, Hiding the Navigation Bar</title>
          <description>&lt;h3&gt;Hide and Show the Navigation Bar to Maximize the View Area&lt;/h3&gt;


	&lt;p&gt;The navigation bar hides while viewing images in Apple&amp;#8217;s Photo app to provide a better view of the image. Hiding the navigation bar is easy. While not exactly the same as the Photo app this technique will hide and show the navigation bar, with an option to animate the transition.&lt;/p&gt;


	&lt;h3&gt;Setup&lt;/h3&gt;


	&lt;p&gt;The method that makes this easy is:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I demonstrate the method in this sample project. To keep it simple, the sample project consists of one view controller, and a single button that toggles the navigation bar between hidden and visible states. This defeats the purpose of a navigation controller, but multiple controllers aren&amp;#8217;t required for this demonstration.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/66/hidenavbar-app.jpg&quot; width=&quot;400px&quot; alt='hidenavbar-app' /&gt;&lt;/p&gt;


	&lt;h3&gt;Getting Started&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;In xCode select File =&amp;gt; New Project, click on Navigation-Based Application and click Choose. &lt;/li&gt;
		&lt;li&gt;Name the project and click Save. I named mine HideNavBar.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Next, simplify the Navigation-Based Application template. In most real world applications Apple&amp;#8217;s template works well. But there are some situations where I would not want a UITableViewController as the RootViewController. Let&amp;#8217;s use a UIViewController instead.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Delete the files RootViewController.h and RootViewController.m. The template added a UITableViewController, and I want to use a UIViewController.&lt;/li&gt;
		&lt;li&gt;Control click Classes and select Add =&amp;gt; New File.&lt;/li&gt;
		&lt;li&gt;Select UIViewController subclass and click Next.&lt;/li&gt;
		&lt;li&gt;Name the file, I used RootViewController.m.&lt;/li&gt;
		&lt;li&gt;Click Finish.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;Add an IBOutlet and an IBAction&lt;/h3&gt;


	&lt;p&gt;Open RootViewController.h and add this code:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@interface RootViewController : UIViewController &amp;lt;UINavigationControllerDelegate&amp;gt; {
    IBOutlet UIButton *button;
}

- (IBAction)toggleNavigationBar:(id)sender;

@property (nonatomic, retain) UIButton *button;

@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Adding an outlet for the button lets you alter the label later. I also added an action to call when the button is clicked. To prevent warnings about the controller not responding to the setNavigationBarHidden:animated: method, I made the controller a UINavigationControllerDelegate.&lt;/p&gt;


	&lt;h3&gt;Change the UI in Interface Builder&lt;/h3&gt;


	&lt;p&gt;The RootViewController is no longer a UITableViewController subclass. Let&amp;#8217;s fix the RootViewController.xib file to handle this.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/67/hidenavbar-ibconfig.jpg&quot; width=&quot;400px&quot; alt='hidenavbar-ibconfig' /&gt;&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Open RootViewController.xib.&lt;/li&gt;
		&lt;li&gt;Delete the TableView.&lt;/li&gt;
		&lt;li&gt;Add a UIView by dragging it from the library.&lt;/li&gt;
		&lt;li&gt;Click on File&amp;#8217;s Owner, and then click Command + i to bring up the inspector.&lt;/li&gt;
		&lt;li&gt;Delete the outlet for the TableView. You will see the button outlet, and the toggleNavigationBar action we added.&lt;/li&gt;
		&lt;li&gt;Double click the View icon to open the view.&lt;/li&gt;
		&lt;li&gt;Drag a UIButton from the library onto the view and position it.&lt;/li&gt;
		&lt;li&gt;Double click the button and enter Hide Navigation Bar.&lt;/li&gt;
		&lt;li&gt;Control click the File&amp;#8217;s owner icon and connect the button outlet by dragging from the outlet to the button that was added. Repeat the process to connect the view outlet to the view.&lt;/li&gt;
		&lt;li&gt;Control click on the button and drag a connection from Touch Up Inside to the File&amp;#8217;s Owner. Connect it to the toggleNavigationBar action.&lt;/li&gt;
		&lt;li&gt;Save and close the file.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Yikes, that seems like a lot of steps. Not to worry, it only takes a minute.&lt;/p&gt;


	&lt;h3&gt;And Now to Make the Navigation Bar Disappear&lt;/h3&gt;


	&lt;p&gt;With all that setup out of the way, let&amp;#8217;s get to the interesting part of the show.&lt;/p&gt;


	&lt;p&gt;Open the HideNavBarAppDelegate.m file and add this to applicationDidFinishLaunching:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {

    //Set the navigation bar style to translucent if there is something that you want to show through.
    navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;

    // Configure and show the window
    [window addSubview:[navigationController view]];
    [window makeKeyAndVisible];
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I added a line to set the barStyle to black translucent. If a picture is in the view below, this allows it to show through while the navigation bar is visible.&lt;/p&gt;


	&lt;p&gt;Open RootViewController.m and complete the implementation.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@synthesize button;

- (IBAction)toggleNavigationBar:(id)sender {
    //Check the current state of the navigation bar...
    BOOL navBarState = [self.navigationController isNavigationBarHidden];
    //Set the navigationBarHidden to the opposite of the current state.
    [self.navigationController setNavigationBarHidden:!navBarState animated:YES];
    //Change the label on the button.
    if (navBarState) {
        [button setTitle:@&quot;Hide Navigation Bar&quot; forState:UIControlStateNormal];
        [button setTitle:@&quot;Hide Navigation Bar&quot; forState:UIControlStateHighlighted];
    } else {
        [button setTitle:@&quot;Show Navigation Bar&quot; forState:UIControlStateNormal];
        [button setTitle:@&quot;Show Navigation Bar&quot; forState:UIControlStateHighlighted];
    }
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I synthesized the button property and added the toggleNavigationBar method. In the first line I set a boolean to the value returned by the isNavigationBarHidden method. The next line calls the setNavigationBarHidden method using the opposite value of the navBarState variable. This allows the navigation bar to be toggled open or closed based on the state it is in. The last few lines of code change the label on the button.&lt;/p&gt;


	&lt;p&gt;The last thing I did was to give the controller a title.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @&quot;Hide Me!&quot;;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Here&amp;#8217;s my test project. &lt;a href=&quot;/assets/65/HideNavBar.zip&quot;&gt;HideNavBar.zip&lt;/a&gt;&lt;/p&gt;</description>
          <pubDate>Fri, 03 Apr 2009 18:56:09 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-uinavigationcontroller-hiding-the-navigation-bar/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-uinavigationcontroller-hiding-the-navigation-bar/</link>
        </item>
    
        <item>
          <title>iPhone SDK: Using Facebook Connect for iPhone, Working with Extended Permissions Part 2 of 2</title>
          <description>&lt;h3&gt;Clearing Up UI Confusion&lt;/h3&gt;


	&lt;p&gt;In part one, I describe using the Facebook Connect for iPhone &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;. In the sample application provided by Facebook, a Get Permission button checks to see if the user has granted the appropriate extended permission to the application. It is a permission to post status updates. The permission needs to be granted only once. If the user clicks the button after permission is granted, they see this message: You have already granted this permission to the application. This begs the question, why display the button after permission is granted?&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/63/fb-screens.jpg&quot; alt=&quot;Sample screens shots of the FB Connect App.&quot; width=&quot;440px&quot; style=&quot;margin-left: -15px;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll provide a sample project at the end of the article. Facebook updates the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; frequently, be sure to get the latest version from the Facebook site. &lt;a href=&quot;http://developers.facebook.com/connect_iphone.php&quot;&gt;Facebook Connect for iPhone&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Plan of Action&lt;/h3&gt;


	&lt;p&gt;The documentation describes the process for working with the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, and provides two samples of interest:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)getUserName { 
    NSString* fql = @&quot;select name from user where uid == 1234&quot;; 
    NSDictionary* params = [NSDictionary dictionaryWithObject:fql forKey:@&quot;query&quot;]; 
    [[FBRequest requestWithDelegate:self] call:@&quot;facebook.fql.query&quot; params:params]; 
} 
- (void)request:(FBRequest*)request didLoad:(id)result { 
    NSArray* users = result; 
    NSDictionary* user = [users objectAtIndex:0]; 
    NSString* name = [user objectForKey:@&quot;name&quot;]; 
    NSLog(@&quot;Query returned %@&quot;, name); 
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;-(void)setUsersStatus { 
    NSString *statusString = exampleTextField.text; 
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: statusString, @&quot;status&quot;, @&quot;true&quot;, @&quot;status_includes_verb&quot;, nil]; 
    [[FBRequest requestWithDelegate:self] call:@&quot;facebook.Users.setStatus&quot; params:params]; 
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Either works. In the first method, replace the &lt;span class=&quot;caps&quot;&gt;FQL&lt;/span&gt; with:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;select status_update from permissions where uid == 1234&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In the second example, use the Users.hasAppPermission method to confirm if the user has opted into the extended permission. Read more about this method here. &lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Users.hasAppPermission&quot;&gt;Users.hasAppPermission&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;For my example, I&amp;#8217;ve decided to go with the first approach. In either case, use this delegate method to process the request:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt; - (void)request:(FBRequest*)request didLoad:(id)result&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The SessionViewController in the sample project is using this method to handle the request used to retrieve the user&amp;#8217;s name:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)request:(FBRequest*)request didLoad:(id)result {
  NSArray* users = result;
  NSDictionary* user = [users objectAtIndex:0];
  NSString* name = [user objectForKey:@&quot;name&quot;];
  _label.text = [NSString stringWithFormat:@&quot;Logged in as %@&quot;, name];
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;To avoid confusion with this code, and to make it easier to reuse in other projects, I&amp;#8217;ll create a class with the sole purpose of tracking the update status permission.&lt;/p&gt;


	&lt;h3&gt;Creating the Permission Status Class&lt;/h3&gt;


	&lt;p&gt;Open the project in the fbconnect-iphone/samples/Connect folder by double clicking the Connect.xcodeproj file.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Right click on the Source group and select Add =&amp;gt; New File.&lt;/li&gt;
		&lt;li&gt;Select Cocoa Touch Classes =&amp;gt; NSObject subclass and then click Next.&lt;/li&gt;
		&lt;li&gt;Name the file PermissionStatus.m and be sure to check the Also Create &amp;#8220;PermissionStatus.h&amp;#8221; check box.&lt;/li&gt;
		&lt;li&gt;Open the PermissionStatus.h file and make it look like this:&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;
#import &quot;FBRequest.h&quot; 

@protocol PermissionStatusDelegate;

@interface PermissionStatus : NSObject &amp;lt;FBRequestDelegate&amp;gt; {
    BOOL userHasPermission;
    id&amp;lt;PermissionStatusDelegate&amp;gt; delegate;
}

@property (nonatomic, assign) BOOL userHasPermission;
@property (nonatomic, retain) id&amp;lt;PermissionStatusDelegate&amp;gt; delegate;

- (PermissionStatus *)initWithUserId:(long long int)uid;

@end

#pragma mark method to call after response
@protocol PermissionStatusDelegate &amp;lt;NSObject&amp;gt;
- (void)statusWasSet:(BOOL)status;
@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;There are a few items of interest here.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;It imports the FBRequest.h header file.&lt;/li&gt;
		&lt;li&gt;It implements the FBRequestDelegate protocol.&lt;/li&gt;
		&lt;li&gt;It defines a protocol of its own, &amp;#8221;@protocol PermissionStatusDelegate;&amp;#8221; that can be used to determine the result of the status check. &lt;/li&gt;
		&lt;li&gt;It contains a property where the delegate can be set.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Next, implement the class as defined in the interface. Open PermissionStatus.m and mimic this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &quot;PermissionStatus.h&quot; 

@implementation PermissionStatus
@synthesize userHasPermission;
@synthesize delegate;

- (PermissionStatus *)initWithUserId:(long long int)uid { 
    self = [super init];

    if (self) {
        NSString* fql = [NSString stringWithFormat:
                         @&quot;select status_update from permissions where uid == %lld&quot;, uid]; 
        NSDictionary* params = [NSDictionary dictionaryWithObject:fql forKey:@&quot;query&quot;]; 
        [[FBRequest requestWithDelegate:self] call:@&quot;facebook.fql.query&quot; params:params]; 
        userHasPermission = NO;
    }
    return self;
} 

#pragma mark FBRequestDelegate
- (void)request:(FBRequest*)request didLoad:(id)result {
    NSArray *permissions = result;
    NSDictionary *permission = [permissions objectAtIndex:0];
    userHasPermission = [[permission objectForKey:@&quot;status_update&quot;] boolValue];
    [delegate statusWasSet:userHasPermission];
}

@end&lt;/code&gt;&lt;/pre&gt;

	&lt;h4&gt;How it works&lt;/h4&gt;


	&lt;p&gt;In the initWithUserId: method, you define the &lt;span class=&quot;caps&quot;&gt;FQL&lt;/span&gt; to retrieve the extended permission and add it to the params dictionary. Instantiate the FBRequest with the PermissionStatus instance as the delegate. I set the userHasPermission property to NO just in case an error occurs with the request. I don&amp;#8217;t care to report any errors, it returns NO if something went wrong. To report an error, use the request:didFailWithError: method to catch the error.&lt;/p&gt;


	&lt;p&gt;In the request:didLoad: method I retrieve the result and call our new delegate method statusWasSet: with the value of the response.&lt;/p&gt;


	&lt;h3&gt;Using the PermissionStatus Class to Hide the Get Permission Button.&lt;/h3&gt;


	&lt;p&gt;First, open SessionViewController.h and make these changes:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Import the new class: &lt;pre&gt;&lt;code&gt;#import &quot;PermissionStatus.h&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Set SessionViewController as a delegate for our class: &lt;pre&gt;&lt;code&gt;&amp;lt;FBDialogDelegate, FBSessionDelegate, FBRequestDelegate, PermissionStatusDelegate&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Add a property to hold an instance of the PermissionStatus class:&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;@interface SessionViewController : UIViewController
    &amp;lt;FBDialogDelegate, FBSessionDelegate, FBRequestDelegate, PermissionStatusDelegate&amp;gt; {
        IBOutlet UILabel* _label;
        IBOutlet UIButton* _permissionButton;
        IBOutlet UIButton* _feedButton;
        IBOutlet FBLoginButton* _loginButton;
        FBSession* _session;
        PermissionStatus *permissionStatusForUser;
}

@property(nonatomic,readonly) UILabel* label;
@property (nonatomic, retain) PermissionStatus *permissionStatusForUser;&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;The Implementation&lt;/h3&gt;


	&lt;p&gt;A few more steps remain to complete the task. Open the SessionViewController.m file and make these changes:&lt;/p&gt;


	&lt;p&gt;Synthesize the property to hold the instance of PermissionStatus&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@synthesize permissionStatusForUser;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Use the dialogDidSucceed: method in the FBDialogDelegate protocol to hide the button if the permission dialog succeeds.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)dialogDidSucceed:(FBDialog*)dialog { 
    _permissionButton.hidden = YES;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Look for the FBSessionDelegate section and instantiate the PermissionStatus class in the session:didLogin: method&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// FBSessionDelegate

- (void)session:(FBSession*)session didLogin:(FBUID)uid {
    //_permissionButton.hidden = NO;
    _feedButton.hidden = NO;

    NSString* fql = [NSString stringWithFormat:
        @&quot;select uid,name from user where uid == %lld&quot;, session.uid];

    NSDictionary* params = [NSDictionary dictionaryWithObject:fql forKey:@&quot;query&quot;];
    [[FBRequest requestWithDelegate:self] call:@&quot;facebook.fql.query&quot; params:params];

        //Instantiate the PermissionStatus class with the user id.
    permissionStatusForUser = [[PermissionStatus alloc] initWithUserId:session.uid];
    permissionStatusForUser.delegate = self;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Implement the statusWasSet: delegate method and set the hidden property of the button to match the status. When done, release the object.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#pragma mark RAD PermissionStatusDelegate
- (void)statusWasSet:(BOOL)status {
    _permissionButton.hidden = status;
    [permissionStatusForUser release];
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Build and run the application. The Get Permission button hides if permission was previously granted.  If not, it remains visible.&lt;/p&gt;


	&lt;p&gt;Here is the sample file. I&amp;#8217;ve removed the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Keys and Template Bundle IDs. Just add the appropriate IDs and enjoy. &lt;a href=&quot;/assets/64/fbconnect-iphone.zip&quot;&gt;fbconnect-iphone.zip&lt;/a&gt;&lt;/p&gt;</description>
          <pubDate>Sun, 22 Mar 2009 01:59:16 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-using-facebook-connect-for-iphone-working-with-extended-permissions-part-2-of-2/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-using-facebook-connect-for-iphone-working-with-extended-permissions-part-2-of-2/</link>
        </item>
    
        <item>
          <title>iPhone SDK: Using Facebook Connect for iPhone Part 1 of 2</title>
          <description>&lt;h3&gt;Sharing with Friends, Now Even Easier&lt;/h3&gt;


	&lt;p&gt;Earlier this week Facebook released Facebook Connect for iPhone, which allows us to connect iPhone apps to the Facebook web site. Facebook Connect for iPhone is a set of classes that can be added to your xCode project and used to ease the process of logging into the site, granting extended permissions and posting status updates to the feed. If you&amp;#8217;d like to read more, check out these articles:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.macworld.com/article/139421/2009/03/facebookconnect.html&quot;&gt;Facebook Connect expands iPhone app social networking&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Find documentation and a how to video here: &lt;a href=&quot;http://developers.facebook.com/connect_iphone.php&quot;&gt;Facebook Connect for iPhone&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The video and information on the Facebook developers page are straight forward and easy to follow. Also, when downloading the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;, a sample project is included that will help you get up and running. I&amp;#8217;ll be using that sample project here.&lt;/p&gt;


	&lt;h4&gt;Missing From the Facebook Documentation&lt;/h4&gt;


	&lt;p&gt;The documentation and the video provided by Facebook assume a certain level of experience creating Facebook apps. The process of creating an App, and creating Template Data for Feed stories was only briefly covered and not explained in their documentation. I&amp;#8217;ll provide a little more background on those tasks here in part one.&lt;/p&gt;


	&lt;p&gt;A Facebook user must grant extended permissions before your app can post a story to the user&amp;#8217;s feed. This is a one time task, and Facebook&amp;#8217;s example demonstrates it nicely. Because it is a one time task, I want to hide the Get Permission button after permission is granted. This process isn&amp;#8217;t covered in Facebook&amp;#8217;s example. I&amp;#8217;ll cover it in part two.&lt;/p&gt;


	&lt;h3&gt;Getting Started with Facebook Connect&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;First, download the Facebook Connect for iPhone &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;. &lt;a href=&quot;http://svn.facebook.com/svnroot/platform/clients/packages/fbconnect-iphone.zip&quot;&gt;Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Unzip it, and take a look inside the fbconnect-iphone/samples/connect folder. Start with the sample project in this folder. The video describes how to add the classes to your project and how to add the path to the source files in the Header Search Path of the Project info. Be sure you do not select &amp;#8220;Copy files into destination group&amp;#8217;s folder if needed&amp;#8221; when adding this to your own project or you may run into problems.&lt;/li&gt;
		&lt;li&gt;In the Connect project, the header path was completed by Facebook. Double click the Connect.xcodeproj file to open the project.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;Creating a New Facebook App&lt;/h3&gt;


	&lt;p&gt;Before moving on, you need a Facebook app to work with as an example. If you haven&amp;#8217;t done so already, sign up with Facebook and login now.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/61/fb-developers.jpg&quot; width=&quot;430px&quot; alt='fb-developers' /&gt;&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;After logging in, go to the &lt;a href=&quot;http://www.facebook.com/developers/&quot;&gt;Developers Page&lt;/a&gt; as seen above. &lt;/li&gt;
		&lt;li&gt;Click on the Set Up New Application button in the upper right hand corner.&lt;/li&gt;
		&lt;li&gt;Give the application a name and click Save Changes. After it saves, you&amp;#8217;ll see the new application screen with the details including the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Key and &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Secret. That&amp;#8217;s all you need.&lt;/li&gt;
		&lt;li&gt;Open SessionViewController.m and add the Application Key and Application Secrect. Replace &amp;#8220;YOUR &lt;span class=&quot;caps&quot;&gt;API KEY&lt;/span&gt;&amp;#8221; and &amp;#8220;YOUR &lt;span class=&quot;caps&quot;&gt;SECRET KEY&lt;/span&gt;&amp;#8221; respectively. Do not leave the &amp;lt;&amp;gt; characters in the string.&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;///////////////////////////////////////////////////////////////////////////////////////////////////
// This application will not work until you enter your Facebook application's API key here:

static NSString* kApiKey = @&quot;&amp;lt;YOUR API KEY&amp;gt;&quot;;

// Enter either your API secret or a callback URL (as described in documentation):
static NSString* kApiSecret = @&quot;&amp;lt;YOUR SECRET KEY&amp;gt;&quot;;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Build and run the application. You can login to facebook and grant your application permission. If you click the Publish to Feed button, an Application Response Error returns, because a template bundle and template bundle ID are not yet defined. Look at this method in the SessionViewController.m file:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)publishFeed:(id)target {
  FBFeedDialog* dialog = [[[FBFeedDialog alloc] init] autorelease];
  dialog.delegate = self;
  dialog.templateBundleId = 9999999;
  dialog.templateData = @&quot;{\&quot;key1\&quot;: \&quot;value1\&quot;}&quot;;
  [dialog show];
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Create a template and replace 9999999 with the correct value.&lt;/p&gt;


	&lt;h3&gt;Creating Feed Templates in Facebook&lt;/h3&gt;


	&lt;p&gt;Creating a feed template isn&amp;#8217;t difficult. However, if you haven&amp;#8217;t done it before, there may be a couple of things that cause you problems. Here&amp;#8217;s more information about &lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Template_Data&quot;&gt;template data.&lt;/a&gt; Each template consists of a one line story, a short story and a full story template. I&amp;#8217;ll use the Feed Template Console to create them.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;In your application&amp;#8217;s page in Facebook, look for the link &amp;#8220;Create Feed Template&amp;#8221; and click it, or for convenience, go to the &lt;a href=&quot;http://developers.facebook.com/tools.php?feed&quot;&gt;Template Console&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Select your application in the drop down and click Next.&lt;/li&gt;
		&lt;li&gt;You&amp;#8217;ll see the Create a One Line Story template screen. Change the text in the One Line Template field to:&lt;pre&gt;&lt;code&gt;{*actor*} won the {*contest*} at the {*event*}.&lt;/code&gt;&lt;/pre&gt; Be sure to include the asterisks on either side of the variable name.&lt;/li&gt;
		&lt;li&gt;The Sample Template Data field shows you how to include images. Replace Facebook&amp;#8217;s data with:&lt;pre&gt;&lt;code&gt;{&quot;contest&quot;:&quot;Pie Eating Contest&quot;, &quot;event&quot;:&quot;California State Fair&quot;}&lt;/code&gt;&lt;/pre&gt;The &amp;#8220;actor&amp;#8221; variable isn&amp;#8217;t needed in the data. For each variable, include a key and a value. The value is replaced with values you provide from your application at run time.&lt;/li&gt;
		&lt;li&gt;Click the Update Preview button. If there are no errors, you will see something like, &amp;#8220;Tim won the Pie Eating Contest at the California State Fair.&amp;#8221; &lt;/li&gt;
		&lt;li&gt;If you&amp;#8217;re happy with the template, click the Next button and create a short story template. This is optional. There are three fields, Short Story Title Template, Short Story Template Body and Sample Template Data. I used these values:&lt;pre&gt;&lt;code&gt;{*actor*} won {*contest*} at {*event*}.&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;{*event*} was a big success and {*actor*} left a thousand dollars richer.&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;{&quot;contest&quot;:&quot;Pie Eating Contest&quot;, &quot;event&quot;:&quot;California State Fair&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Rinse, wash and repeat. Click the Update Preview button and confirm there are no errors. &lt;/li&gt;
		&lt;li&gt;Click next, and if you want to create a full story go ahead. I clicked Skip on the Full Story screen.&lt;/li&gt;
		&lt;li&gt;The Create an Action Link screen opens. Using the console, Facebook allows only one action link. Use it wisely. Enter &amp;#8220;Visit my site&amp;#8221; in the Action Link Text field, and a link to your web site or fan page in the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; field, click Update Preview. The link updates in the preview and you can test it.&lt;/li&gt;
		&lt;li&gt;When ready, click Next, and click Register Template Bundle. The bundle id is displayed. Copy it into the code, replace 9999999 with the correct id, and change the templatData like this:&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;- (void)publishFeed:(id)target {
  FBFeedDialog* dialog = [[[FBFeedDialog alloc] init] autorelease];
  dialog.delegate = self;
  dialog.templateBundleId = 9999999;
  dialog.templateData = @&quot;{\&quot;contest\&quot;:\&quot;Pie Eating Contest\&quot;, \&quot;event\&quot;:\&quot;California State Fair\&quot;}&quot;;
  [dialog show];
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I did not enter the template bundle ID in the sample code above, be sure to replace it. Build and run the application. Post the feed to Facebook. Of course when formatting the template data, replace the hard coded values with variables from your application.&lt;/p&gt;</description>
          <pubDate>Sat, 21 Mar 2009 22:39:44 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-using-facebook-connect-for-iphone-part-1-of-2/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-using-facebook-connect-for-iphone-part-1-of-2/</link>
        </item>
    
        <item>
          <title>iPhone SDK: Resizing a UITableViewCell to Hold Variable Amounts of Text, Part 2 of 2</title>
          <description>&lt;h3&gt;Completing the UITextView Example&lt;/h3&gt;


	&lt;p&gt;In part one, I demonstrated how to use a UITextView and a UITableViewCell to create a field for users to enter large amounts of text. After the text is saved, I&amp;#8217;d like to display that text in a different table. The problem is I don&amp;#8217;t know the height of the text. I&amp;#8217;ll tackle that problem now.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/60/variabletableviewcell.jpg&quot; width=&quot;440px&quot; style=&quot;margin-left: -15px;&quot; alt='variabletableviewcell' /&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll be starting with the project that I created in part one. If you want to follow along, here&amp;#8217;s the sample project prior to these changes: &lt;a href=&quot;/assets/55/UITextView.zip&quot;&gt;UITextView&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Calculating the Height of the Text in the Field&lt;/h3&gt;


	&lt;p&gt;The first thing that I need to do is determine the height of the text that will be displayed. Luckily, there is a method to do just that in the NSString class.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;As you can see, we need to know the font, the size of the area the text will be constrained to, and the mode for the line breaks. In this case, the font will be a system font. Since I will be doing this repeatedly, and I&amp;#8217;d like to use this method without repeating myself, I&amp;#8217;ve decided to create a category for NSString. Categories are a convenient way to extend objective-C classes. If your unsure about how they work, here is a good article that may help. &lt;a href=&quot;http://it.toolbox.com/blogs/macsploitation/extending-classes-in-objectivec-with-categories-27447&quot;&gt;Extending Classes In Objective-C with Categories&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Create an NSString Category&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;In Xcode control click on the Classes group under Groups and Files.&lt;/li&gt;
		&lt;li&gt;Select Add &amp;gt; New File to create a new file.&lt;/li&gt;
		&lt;li&gt;Select Cocoa Touch Classes, click on NSObject subclass, and click Next. Name the file StringHelper.m. Make sure you have &amp;#8220;Also create &amp;#8216;StringHelper.h&amp;#8217;&amp;#8221; checked.&lt;/li&gt;
		&lt;li&gt;Open the StringHelper.h file and change it like this:&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;

@interface NSString (StringHelper)
  - (CGFloat)RAD_textHeightForSystemFontOfSize:(CGFloat)size;
@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Notice that I removed the NSObject subclass. The interface defines a new category for NSString, and names it StringHelper. I also added the definition for my method to determine the height of the text. Bascially, I&amp;#8217;ll be using a cell that is always the same width, so the height is the value I&amp;#8217;m interested in. In other situations you may need more flexibility. To keep it simple, I decided to allow for only one variable, the font size. I prefixed it with &lt;span class=&quot;caps&quot;&gt;RAD&lt;/span&gt; only as a convention, and to avoid name conflicts. Here&amp;#8217;s the implementation:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &quot;StringHelper.h&quot; 

@implementation NSString (StringHelper)

- (CGFloat)RAD_textHeightForSystemFontOfSize:(CGFloat)size {
    //Calculate the expected size based on the font and linebreak mode of the label
    CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 50;
    CGFloat maxHeight = 9999;
    CGSize maximumLabelSize = CGSizeMake(maxWidth,maxHeight);

    CGSize expectedLabelSize = [self sizeWithFont:[UIFont systemFontOfSize:size] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; 

    return expectedLabelSize.height;
}

@end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;First define the maximum width, I&amp;#8217;m setting it to be 50 pixels narrower than the width of the screen. Then the maximum height. I then use the CGSizeMake method with the maxWidth and maxHeight variables to create a maximum label size variable that will be passed to the sizeWithFont: contstrainedToSize: lineBreakMode method. I am only interested in the height for my table view cell, so I return only the height.&lt;/p&gt;


	&lt;p&gt;Now I know the height of the cell. I also need to create a label to go into the cell. The label will need to be initiated with the proper width, height and properties for the font. Once again, I&amp;#8217;d like to make it convenient to re-use in my application, so let&amp;#8217;s create another helper method. Since it still depends on the string, add this method to the StringHelper Category too.&lt;/p&gt;


	&lt;p&gt;Add this to the StringHelper.h file:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (UILabel *)RAD_sizeCellLabelWithSystemFontOfSize:(CGFloat)size;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This method will return a UILabel sized to hold our text. Here&amp;#8217;s the implementation:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (UILabel *)RAD_sizeCellLabelWithSystemFontOfSize:(CGFloat)size {
    CGFloat width = [UIScreen mainScreen].bounds.size.width - 50;
    CGFloat height = [self RAD_textHeightForSystemFontOfSize:size] + 10.0;
    CGRect frame = CGRectMake(10.0f, 10.0f, width, height);
    UILabel *cellLabel = [[UILabel alloc] initWithFrame:frame];
    cellLabel.textColor = [UIColor blackColor];
    cellLabel.backgroundColor = [UIColor clearColor];
    cellLabel.textAlignment = UITextAlignmentLeft;
    cellLabel.font = [UIFont systemFontOfSize:size];

    cellLabel.text = self; 
    cellLabel.numberOfLines = 0; 
    [cellLabel sizeToFit];
    return cellLabel;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The first two lines determine the width and height for the label&amp;#8217;s frame. To get the height, I re-used the helper method defined previously. Use these values to create a CGRect that defines the rectangle the label will occupy. After that, initialize the label and set a few properties for color, alignment, and font. Set the text of the label to the string. Setting the numberOfLines property of the cellLabel to 0 removes any maximum limit to the number of lines.&lt;/p&gt;


	&lt;p&gt;With these two methods we have everything we need to define our table view cell with a label that will hold long strings.&lt;/p&gt;


	&lt;h3&gt;Configure the Table View&lt;/h3&gt;


	&lt;p&gt;Configuring the table view is fairly easy. Import the StringHelper.h file. I also defined two constants to give myself an easy way to change the values. Add this to the top of the RootViewController.m file.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &quot;StringHelper.h&quot; 

//Text View contstants
#define kTextViewFontSize        18.0
#define kDefaultNoteLabel        @&quot;Add a Note&quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Define the height for the row that will hold the cell:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  {  
    NSString *label = [self.aNote length] == 0 ? kDefaultNoteLabel : self.aNote;
    CGFloat height = [label RAD_textHeightForSystemFontOfSize:kTextViewFontSize] + 20.0;
    return height;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Nothing special going on here. If the aNote variable is empty, use the &amp;#8220;Add a Note&amp;#8221; string as the label. Then use the StringHelper method to calculate the height. I added a little extra space to the height of the cell so that the label would fit comfortably within the cell.&lt;/p&gt;


	&lt;p&gt;Finally, define the cell with the label.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @&quot;NoteCell&quot;;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    //Working with a resizable note cell
    //If there is already a subview, remove it.
    if ([[cell.contentView subviews] count] &amp;gt; 0) {
        UIView *labelToClear = [[cell.contentView subviews] objectAtIndex:0];
        [labelToClear removeFromSuperview];
    }

    UILabel *cellLabel;
    NSString *label = [self.aNote length] == 0 ? kDefaultNoteLabel : self.aNote;

    cellLabel = [label RAD_sizeCellLabelWithSystemFontOfSize:kTextViewFontSize];

    [cell.contentView addSubview:cellLabel];
    [cellLabel release];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.hidesAccessoryWhenEditing = YES;
    return cell;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This code defines a label using the helper method and then adds the label as a subview to the cell. If the aNote variable is empty, it uses the &amp;#8220;Add a Note&amp;#8221; string as the label, otherwise it uses the value of the variable. Before adding the subview, it checks to see if any subviews already exist. If one does, it is removed. This prevents text from being layered on top of other subviews. Which isn&amp;#8217;t pretty. Unless your going for a grungy look.&lt;/p&gt;


	&lt;p&gt;There&amp;#8217;s still one task left. If we build and run the project now, everything should compile, and the &amp;#8220;Add a Note&amp;#8221; text should appear with a properly sized cell. The problem is that after we enter text and return to this view, our new text will not be displayed. To take care of this, we need to add an IBOutlet for the table view and wire it up in Interface Builder so that we can reload the data.&lt;/p&gt;


	&lt;h3&gt;Add an IBOutlet in Interface Builder&lt;/h3&gt;


	&lt;p&gt;First add an outlet to the RootViewController.h file:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@interface RootViewController : UITableViewController {
    AddNoteViewController *addNoteController;
    IBOutlet UITableView *tbView;
    NSString *aNote;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Note: The RootViewController.xib file already contains an outlet called tableView that may be used. If you add an outlet with the same name you won&amp;#8217;t have to change anything in Interface Builder. I like to give the table view a different name to help me keep it clear when debugging, but there is no real need to do this. If you change the name as I did, just open the file in IB, delete the old outlet and connect the new one.&lt;/p&gt;


	&lt;p&gt;When the view appears, tell the table view to reload data.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)viewDidAppear:(BOOL)animated {
    [tbView reloadData];
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;That&amp;#8217;s it. At this point you should be able to build the project, add a note, and see the whole note in the cell when done. Removing or adding text to the note should also resize the cell after saving.&lt;/p&gt;


	&lt;h3&gt;Re-factoring to Improve Performance&lt;/h3&gt;


	&lt;p&gt;Thanks to Deegee&amp;#8217;s comment below, I decided to re-factor the code to resize the label if it already exists.&lt;/p&gt;


	&lt;p&gt;Here are the changes:&lt;/p&gt;


	&lt;p&gt;First I created two new helper methods in the category like this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (CGRect)RAD_frameForCellLabelWithSystemFontOfSize:(CGFloat)size {
    CGFloat width = [UIScreen mainScreen].bounds.size.width - 50;
    CGFloat height = [self RAD_textHeightForSystemFontOfSize:size] + 10.0;
    return CGRectMake(10.0f, 10.0f, width, height);
}

- (void)RAD_resizeLabel:(UILabel *)aLabel WithSystemFontOfSize:(CGFloat)size {
    aLabel.frame = [self RAD_frameForCellLabelWithSystemFontOfSize:size];
    aLabel.text = self;
    [aLabel sizeToFit];
}
&lt;/code&gt;&lt;/pre&gt; 

	&lt;p&gt;The &lt;span class=&quot;caps&quot;&gt;RAD&lt;/span&gt;_frameForCellLabelWithSystemFontOfSize: method is simply to help keep the code dry. I pulled it into a new method rather than repeating those lines of code.&lt;/p&gt;


	&lt;p&gt;I then changed the code in the RootViewController.m file as follows:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @&quot;NoteCell&quot;;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    NSString *label = [self.aNote length] == 0 ? kDefaultNoteLabel : self.aNote;

    //Working with a resizable note cell
    //If there is already a subview, resize it, else create it.
    if ([[cell.contentView subviews] count] &amp;gt; 0) {
        id view = [[cell.contentView subviews] objectAtIndex:0];
        UILabel *labelToSize = view;
        [label RAD_resizeLabel:labelToSize WithSystemFontOfSize:kTextViewFontSize];
    } else {
        UILabel *cellLabel;
        cellLabel = [label RAD_newSizedCellLabelWithSystemFontOfSize:kTextViewFontSize];
        [cell.contentView addSubview:cellLabel];
        [cellLabel release];
    }

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.hidesAccessoryWhenEditing = YES;
    return cell;
}&lt;/code&gt;&lt;/pre&gt; 

Finally, I renamed the method that creates a new label to indicate that it would be returning a new label as follows:
&lt;pre&gt;&lt;code&gt;- (UILabel *)RAD_newSizedCellLabelWithSystemFontOfSize:(CGFloat)size;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Here&amp;#8217;s the sample project: &lt;a href=&quot;/assets/59/UITextView2.zip&quot;&gt;UITextView2.zip&lt;/a&gt;&lt;/p&gt;</description>
          <pubDate>Sat, 14 Mar 2009 00:56:08 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-resizing-a-uitableviewcell-to-hold-variable-amounts-of-text/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-resizing-a-uitableviewcell-to-hold-variable-amounts-of-text/</link>
        </item>
    
        <item>
          <title>iPhone SDK: Using a UITableViewCell with a UITextView for Entering Text, Part 1 of 2</title>
          <description>&lt;h3&gt;When a Simple Text Field Won&amp;#8217;t Do&lt;/h3&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/56/iphone-notes.jpg&quot; style=&quot;float: right; margin: 0px 0px 10px 10px;&quot; alt='iphone-notes' /&gt;When entering lots of text, sometimes a simple text field won&amp;#8217;t do the trick. Especially if you want to imitate the look of Apple Applications such as iCal. You need to use a table view and a custom table view cell, as I will demonstrate. Apple provides a good example of this using code. I&amp;#8217;ll demonstrate how to do the same trick using Interface Builder. Apple&amp;#8217;s sample: &lt;a href=&quot;http://developer.apple.com/iphone/samples/index.action#UICatalog&quot;&gt;UICatalog&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This is a two part blog. Part one describes how to create a text entry field. Part two, will describe displaying variable amounts of text in a table view cell, and adjusting the height of the cell to hold all of the text. Creating a controller for entering text, and a controller to display all of the text in a table view cell is the goal.&lt;/p&gt;


	&lt;h3&gt;UITextView Project Overview&lt;/h3&gt;


	&lt;p&gt;In this project, I created an application with two screens. The first screen provides a button to open the second screen where text is entered. Both screens use grouped UITableViewControllers. You will build the app, move from screen to screen, enter any amount of text into the field, and save it.&lt;/p&gt;


	&lt;h4&gt;Get Started with a Navigation-Based Project&lt;/h4&gt;


	&lt;ol&gt;
	&lt;li&gt;First, create a new project in Xcode and select the Navigation-Based Project. I named mine UITextView.&lt;/li&gt;
		&lt;li&gt;Open the RootViewController.xib file in the resources group, select the Table View and type Command + 1 to open the inspector. Change the style from Plain to Grouped and save the file.&lt;/li&gt;
		&lt;li&gt;Control click on the classes group and select Add &amp;gt; Add New File. Select Cocoa Touch Classes, and select the UITableViewController Subclass template. I named mine AddNoteViewController. This is the controller to manage the text view. &lt;/li&gt;
		&lt;li&gt;Open AddNoteViewController.h and add the following code:&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;@interface AddNoteViewController : UITableViewController &amp;lt;UITextViewDelegate&amp;gt; {
    IBOutlet UITableView *tbView;
    NSString *aNote;
}
@property (nonatomic, retain) NSString *aNote;

- (void)save:(id)sender;

@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Be sure to make the class a UITextViewDelegate.&lt;/p&gt;


	&lt;p&gt;With an IBOutlet for the table view, create the nib file.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Control click on the Resources group in Xcode.&lt;/li&gt;
		&lt;li&gt;Select Add &amp;gt; Add New File and then click on User Interfaces. Click on Empty &lt;span class=&quot;caps&quot;&gt;XIB&lt;/span&gt; and then click on Next and name the file AddNoteView.xib.&lt;/li&gt;
		&lt;li&gt;Double click on the new file to open it, it should have only the File&amp;#8217;s Owner and First Responder objects in it.&lt;/li&gt;
		&lt;li&gt;Drag a UITableView from the Library into the file.&lt;/li&gt;
		&lt;li&gt;Click on File&amp;#8217;s Owner and then type Command + 4 to open the Class Identity inspector.&lt;/li&gt;
		&lt;li&gt;Set the class of File&amp;#8217;s Owner to our controller AddNoteViewController. You should see the tbView outlet that we defined previously.&lt;img src=&quot;/assets/57/addnote-ibconnections.jpg&quot; style=&quot;float:right; margin: 0px 0px 10px 10px;&quot; alt='addnote-ibconnections' /&gt;&lt;/li&gt;
		&lt;li&gt;Now control click on the File&amp;#8217;s Owner. When the gray box pops up, connect the tbView outlet to the Table View. &lt;/li&gt;
		&lt;li&gt;Also connect the view outlet to the Table View.&lt;/li&gt;
		&lt;li&gt;Then control click on the table view and connect the datasource and delegate outlets to be the files owner.&lt;/li&gt;
		&lt;li&gt;Lastly, with the Table View selected, click Command + 1 to bring up the inspector and change the style of the table to Grouped.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;When done, save and close the nib file.&lt;/p&gt;


	&lt;h3&gt;Load the New Controller from the RootViewController&lt;/h3&gt;


	&lt;p&gt;With the initial parts of the AddNoteViewController in place, wire up the RootViewController such that the AddNoteView loads when clicked. Open RootViewController.h and enter this code:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;
#import &quot;AddNoteViewController.h&quot; 

@interface RootViewController : UITableViewController {
    AddNoteViewController *addNoteController;
    NSString *aNote;
}

@property (nonatomic, retain) AddNoteViewController *addNoteController;
@property (nonatomic, retain) NSString *aNote;
@end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This imports the new controller and adds a variable for it. I also added a variable to hold a note string. I won&amp;#8217;t be using it just yet.&lt;/p&gt;


	&lt;p&gt;Next, open the RootViewController.m file. First synthesize our two variables.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@synthesize addNoteController;
@synthesize aNote;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I added a title in the viewDidLoad method.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @&quot;My Note&quot;;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Change the table view methods as follows:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @&quot;Cell&quot;;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell...
    cell.text = @&quot;Add a Note&quot;;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    return cell;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now we have a cell to click on. To handle the click, edit the tableView:didSelectRowAtIndexPath method as follows:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    addNoteController = [[AddNoteViewController alloc] initWithNibName:@&quot;AddNoteView&quot; bundle:nil];
    addNoteController.title = @&quot;My Notes&quot;;
    addNoteController.aNote = self.aNote;

    [self.navigationController pushViewController:addNoteController animated:YES];
    [addNoteController release];    
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Build and run the application. Click on the Add a Note row, and the AddNoteViewController will load up. It won&amp;#8217;t do anything yet, but this is a good time to debug and clean up any errors.&lt;/p&gt;


	&lt;h3&gt;Build the UITextView&lt;/h3&gt;


	&lt;p&gt;Before we can load the AddNoteViewController with the TextView, we need to define a custom cell to hold it. We&amp;#8217;ll then load that cell into the table view.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;In Xcode, control click on the Classes group and select Add &amp;gt; Add New File.&lt;/li&gt;
		&lt;li&gt;Select Cocoa Touch Classes, and then click on UITableViewCell subclass and click next. Name your file TextViewCell.&lt;/li&gt;
		&lt;li&gt;Open the TextFieldCell.h file and add the following code:&lt;/li&gt;
	&lt;/ol&gt;


&lt;pre&gt;&lt;code&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;

// cell identifier for this custom cell
extern NSString *kCellTextView_ID;

@interface TextViewCell : UITableViewCell {
    IBOutlet UITextView *textView;
}
+ (TextViewCell*) createNewTextCellFromNib;

@property (nonatomic, retain) UITextView *textView;

@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This defines an IBOutlet to access the UITextView. We also define a method to create the cell from a nib file. Before we create the nib file, let&amp;#8217;s finish the implementation. Open TextViewCell.m and add the following:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &quot;TextViewCell.h&quot; 

// cell identifier for this custom cell
NSString* kCellTextView_ID = @&quot;CellTextView_ID&quot;;

@implementation TextViewCell
@synthesize textView;

//Helper method to create the workout cell from a nib file...
+ (TextViewCell*) createNewTextCellFromNib { 
    NSArray* nibContents = [[NSBundle mainBundle] loadNibNamed:@&quot;TextViewCell&quot; owner:self options:nil]; 
    NSEnumerator *nibEnumerator = [nibContents objectEnumerator]; 
    TextViewCell* tCell = nil; 
    NSObject* nibItem = nil; 
    while ( (nibItem = [nibEnumerator nextObject]) != nil) { 
        if ( [nibItem isKindOfClass: [TextViewCell class]]) { 
            tCell = (TextViewCell*) nibItem; 
            if ([tCell.reuseIdentifier isEqualToString: kCellTextView_ID]) 
                break; // we have a winner 
            else 
                tCell = nil; 
        } 
    } 
    return tCell; 
} 

- (void)dealloc
{
    [textView release];
    [super dealloc];
}

@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This initializes our cell using a nib file that we haven&amp;#8217;t created yet. Let&amp;#8217;s do that now.&lt;/p&gt;


	&lt;h3&gt;Creating a Cell Template in Interface Builder&lt;/h3&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/58/TextViewCell.jpg&quot; width=&quot;430px&quot; alt='TextViewCell' /&gt;&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;First, control click on the resources folder in Xcode and select Add &amp;gt; Add New File.&lt;/li&gt;
		&lt;li&gt;Select User Interfaces, and then select Empty &lt;span class=&quot;caps&quot;&gt;XIB&lt;/span&gt;. Name the file TextViewCell.xib, and then double click to open it.&lt;/li&gt;
		&lt;li&gt;In the Library, find a UITableViewCell and drag it into the nib file.&lt;/li&gt;
		&lt;li&gt;Select the cell, and click Command + 4 to open the class inspector.&lt;/li&gt;
		&lt;li&gt;Set the class of the cell to TextViewCell, the class that we defined earlier.&lt;/li&gt;
		&lt;li&gt;Click Command + 1 to open the Attributes inspector and enter &amp;#8220;CellTextView_ID&amp;#8221; in  the Identifier field.&lt;/li&gt;
		&lt;li&gt;Click on the Size tab of the inspector and enter 150 in the height field.&lt;/li&gt;
		&lt;li&gt;Double click on the table view cell to open it and drag a TextView onto the cell.&lt;/li&gt;
		&lt;li&gt;Size the TextView to fit into the cell nicely. Then double click it and remove the sample text from the field.&lt;/li&gt;
		&lt;li&gt;Finally, control click on the cell and drag from the textView outlet to the Text View that we added.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;When done, save the file and close it. We&amp;#8217;re getting close now, I promise.&lt;/p&gt;


	&lt;h3&gt;Implement the AddNoteViewController&lt;/h3&gt;


	&lt;p&gt;This is our final step. Open the AddNoteViewController.m file and add this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#import &quot;AddNoteViewController.h&quot; 
#import &quot;RootViewController.h&quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I&amp;#8217;m importing the root view controller here only to access the note variable to simulate saving the data. In a real application I would use a model class and save the data to a database or file.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;//Text View contstants
#define kUITextViewCellRowHeight 150.0&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Store a value that will be used to define the height of the cell in the table view.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@implementation AddNoteViewController
@synthesize aNote;

- (void)save:(id)sender
{
    /*
     Save data from the text view to the variable and then pop back to the root view.
     Normally , this is where I would save data to the database. To keep the example simple
     I am simply setting the variable in the root controller to match that of my note.
    */

    TextViewCell *cell = (TextViewCell *) [tbView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    self.aNote = [cell.textView text];
    NSLog(self.aNote);
    RootViewController *rootController = [self.navigationController.viewControllers objectAtIndex:0];
    rootController.aNote = self.aNote;
    [self.navigationController popViewControllerAnimated:YES];
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The save method retrieves the value of the TextView and assigns it to the variable aNote. In this case I also assign it to the variable in the root view controller to use the next time the AddNoteViewController is loaded.&lt;/p&gt;


	&lt;p&gt;In the viewDidLoad method, add a button to save our text. Since I am popping back to the root view controller after saving, I don&amp;#8217;t have to dismiss the keyboard.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;- (void)viewDidLoad {
    [super viewDidLoad];

    // provide a Save button to dismiss the keyboard
    UIBarButtonItem* saveItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save:)];
    self.navigationItem.rightBarButtonItem = saveItem;
    [saveItem release];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

#pragma mark Table view methods
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewCellEditingStyleNone;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat result;
    result = kUITextViewCellRowHeight;    
    return result;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This sets the height of the cell to the value of the constant that was defined earlier.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    TextViewCell *cell = (TextViewCell *) [tableView dequeueReusableCellWithIdentifier:kCellTextView_ID];

    if (cell == nil) {
        cell = [TextViewCell createNewTextCellFromNib];
    }

    // Set up the cell...
    cell.textView.text = self.aNote;
    [cell.textView becomeFirstResponder];
    cell.textView.delegate = self;
    return cell;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Here we call the method in our TextViewCell,  createNewTextCellFromNib, only if the cell is nil. Set the text property of the textView to the value of the aNote variable, and make the textView the first responder to display the keyboard. Finally set the delegate to self.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#pragma mark UITextView delegate methods
- (void)textViewDidBeginEditing:(UITextView *)textView
{

}

- (void)dealloc {
    [super dealloc];
}
@end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I didn&amp;#8217;t do anything with the delegate method, but I left it to show how things can be handled.&lt;/p&gt;


	&lt;p&gt;At this point, everything should be in place. You can build and run the project. Click on Add a Note, enter a note and click save. When clicking on Add a Note a second time, you should see your previous note.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the sample project: &lt;a href=&quot;/assets/55/UITextView.zip&quot;&gt;UITextView&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Stay tuned for part 2, which will be ready at the end of the week.&lt;/p&gt;</description>
          <pubDate>Sat, 07 Mar 2009 22:57:05 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-using-a-uitableviewcell-with-a-uitextview-for-entering-text-part-1-of-2/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-using-a-uitableviewcell-with-a-uitextview-for-entering-text-part-1-of-2/</link>
        </item>
    
        <item>
          <title>iPhone SDK: UITabBarController,  How to Save User Customized Tab Order</title>
          <description>&lt;h3&gt;Even with Apple's iPhone SDK, There's No Free Lunch.&lt;/h3&gt;&lt;p&gt;With the UITabBarController Apple has provided tons of functionality for free. One
thing that the UITabBarController does not do is save the order of the
tabs when a user changes them, so we have to do that
task by ourselves.&lt;/p&gt;&lt;h3&gt;UITabBarController Class: Quick Background&lt;/h3&gt;&lt;p&gt;The UITabBarController class in the iPhone SDK enables users to move between multiple view controllers with a click of a tab at the bottom of the screen. If you have more than five tabs in your application, it also offers a More tab. When tapped, it displays the additional tabs in a table for users to select them. When in the More tab of the application, clicking on the &quot;Edit&quot; button brings up a view where users can customize the order of the tabs to suit their own needs. &lt;/p&gt;&lt;p&gt;While they can re-order the tabs, unless we take a few steps in our code, their settings won't be saved.&lt;/p&gt;&lt;h4&gt;Overview: Saving Customized Tab Order&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;When the application quits, save the current order of the tabs to an array in the user defaults. &lt;/li&gt;&lt;li&gt;The next time it opens, retrieve the saved order of the tabs from the defaults.&lt;/li&gt;&lt;li&gt;Loop through the view controllers and place them into an array with the saved order.&lt;/li&gt;&lt;li&gt;Provide the newly ordered array to the UITabBarController for display.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I'm going to go step by step through the process with an example that does not use Interface Builder to define the UITabBarController only because it makes it a little easier to understand how the array of controllers is created.&amp;#160; I did the example both ways so both example projects are attached.&lt;/p&gt;&lt;h3&gt;UITabBarController Project Setup&lt;/h3&gt;&lt;p&gt;I created a new project in Xcode using the Window Based Applicaiton template. Because I'm a little lazy, I opted to reuse the same controller and view in each of the tabs. The view has a single label in it that is changed to match the title of each tab.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Right click on the classes group and select add new file.&lt;/li&gt;&lt;li&gt;Select Cocoa Touch Classes, and then select UIViewController Subclass and give it a name. I named mine AllTabsViewController.&lt;/li&gt;&lt;li&gt;In the AllTabsViewController.h file add the following code:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;@interface AllTabsViewController : UIViewController {&lt;br /&gt;	IBOutlet UILabel *nameLabel;&lt;br /&gt;}&lt;br /&gt;@property (nonatomic, retain) UILabel *nameLabel;&lt;br /&gt;@end&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Right click on resources folder in Xcode and add a new file. This time select User Interfaces and then select View XIB. I named my nib file AllTabsView.xib.&lt;br /&gt;&lt;img src=&quot;/assets/53/class-settings-in-ib.jpg&quot; width=&quot;375px&quot; style=&quot;margin: 10px 0px 10px 0px;&quot; alt='filesowner-class' /&gt;&lt;/li&gt;&lt;li&gt;Open the new nib file, select the File's Owner icon and then change the class to AllTabsViewController in the Identity inspector. You should see the nameLabel outlet in the Class Outlets portion of the screen.&lt;/li&gt;&lt;li&gt;Drag a label from the library onto the view. I centered mine and made it nice and big.&lt;/li&gt;&lt;li&gt;&lt;img src=&quot;/assets/54/ib-connection-tabs.jpg&quot; style=&quot;float: right; margin: 10px 0px 10px 10px;&quot; alt='ib-connection-tabs' /&gt;Control click on the File's Owner icon and drag from the nameLabel outlet to the label we added. Also drag from the view outlet to the view in our nib file.&lt;/li&gt;&lt;li&gt;When done, close InterfaceBuilder.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Start by Adding Tabs to the Tab Bar Controller&lt;/h3&gt;&lt;p&gt;Next we'll set up the application to build the tabs and load the controllers. &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Back in Xcode, open the AllTabsViewContrller.m file to finish the implementation of the view controller.&lt;/li&gt;&lt;li&gt;First, synthesize our property for the label:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;@synthesize nameLabel;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;While we're at it, let's go ahead and make sure it get's released to:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;- (void)dealloc {&lt;br /&gt;    [nameLabel release];&lt;br /&gt;    [super dealloc];&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;The only other thing to do here is change the label when the view loads. Go to the viewDidLoad method and add the following code:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;- (void)viewDidLoad {&lt;br /&gt;    nameLabel.text = self.title;&lt;br /&gt;    [super viewDidLoad];&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Now open the app delegete class header file, in my case it is called TabBarSaveStateAppDelegate.h. We need to make it a UITabBarController delegate and add a tabBarController porperty. When done it should look like this:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;#import &quot;AllTabsViewController.h&quot;&lt;br /&gt;&lt;br /&gt;@interface TabBarSaveStateAppDelegate : NSObject &amp;lt;UIApplicationDelegate, UITabBarControllerDelegate&amp;gt; {&lt;br /&gt;    UIWindow *window;&lt;br /&gt;    UITabBarController *tabController;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) IBOutlet UIWindow *window;&lt;br /&gt;@property (nonatomic, retain) UITabBarController *tabController;&lt;br /&gt;@end&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Finally, edit the implementation file to populate our tab controller. Open TabBarSaveStateAppDelegate.m and add the following code.&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;@implementation TabBarSaveStateAppDelegate&lt;br /&gt;&lt;br /&gt;@synthesize window;&lt;br /&gt;@synthesize tabController;&lt;br /&gt;&lt;br /&gt;- (void)applicationDidFinishLaunching:(UIApplication *)application {    &lt;br /&gt;	tabController = [[UITabBarController alloc] init];&lt;br /&gt;	tabController.delegate = self;&lt;br /&gt;&lt;br /&gt;	//Add some tabs to the controller...&lt;br /&gt;	AllTabsViewController *firstTabController = [[AllTabsViewController alloc] initWithNibName: @&quot;AllTabsView&quot; bundle: nil];&lt;br /&gt;	firstTabController.title = @&quot;Tab One&quot;;&lt;br /&gt;&lt;br /&gt;	AllTabsViewController *secondTabController = [[AllTabsViewController alloc] initWithNibName: @&quot;AllTabsView&quot; bundle: nil];&lt;br /&gt;	secondTabController.title = @&quot;Tab Two&quot;;&lt;br /&gt;&lt;br /&gt;	AllTabsViewController *thirdTabController = [[AllTabsViewController alloc] initWithNibName: @&quot;AllTabsView&quot; bundle: nil];&lt;br /&gt;	thirdTabController.title = @&quot;Tab Three&quot;;&lt;br /&gt;&lt;br /&gt;	AllTabsViewController *fourthTabController = [[AllTabsViewController alloc] initWithNibName: @&quot;AllTabsView&quot; bundle: nil];&lt;br /&gt;	fourthTabController.title = @&quot;Tab Four&quot;;&lt;br /&gt;&lt;br /&gt;	AllTabsViewController *fifthTabController = [[AllTabsViewController alloc] initWithNibName: @&quot;AllTabsView&quot; bundle: nil];&lt;br /&gt;	fifthTabController.title = @&quot;Tab Five&quot;;&lt;br /&gt;&lt;br /&gt;	AllTabsViewController *sixthTabController = [[AllTabsViewController alloc] initWithNibName: @&quot;AllTabsView&quot; bundle: nil];&lt;br /&gt;	sixthTabController.title = @&quot;Tab Six&quot;;&lt;br /&gt;&lt;br /&gt;	tabController.viewControllers = [NSArray arrayWithObjects:firstTabController, secondTabController, thirdTabController, fourthTabController, fifthTabController, sixthTabController, nil];&lt;br /&gt;&lt;br /&gt;	[firstTabController release];&lt;br /&gt;	[secondTabController release];&lt;br /&gt;	[thirdTabController release];&lt;br /&gt;	[fourthTabController release];&lt;br /&gt;	[fifthTabController release];&lt;br /&gt;	[sixthTabController release];&lt;br /&gt;&lt;br /&gt;	[window addSubview:tabController.view];&lt;br /&gt;&lt;br /&gt;    // Override point for customization after application launch&lt;br /&gt;    [window makeKeyAndVisible];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- (void)dealloc {&lt;br /&gt;    [window release];&lt;br /&gt;    [tabController release];&lt;br /&gt;    [super dealloc];&lt;br /&gt;}&lt;/pre&gt;This code instantiates six view controllers and gives each a unique title. The title will appear on the tab, and on the label in the view itself. &lt;br /&gt;&lt;br /&gt;It then adds each of the view controllers to an array called viewControllers that is a property of the UITabBarController class. Finally it adds the view to a subview of the window.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;You should be able to build and run the application. Click on the More tab, edit the order of the tabs. If you close and re-open the application, you should notice that the order you set for the tabs is lost. The tabs will be in the default order. We'll take care of that next.&lt;/p&gt;&lt;h3&gt;Saving the Tab Order When the Application Closes&lt;/h3&gt;&lt;p&gt;Now that our sample is all set up, I'll take care of the problem I set out to solve in the first place. We'll be doing all this in the AppDelegate class. Open TabBarSaveStateAppDelegate.m again.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The application delegate provides a method that will be called when the application terminates called applicationWillTerminate:. We'll use it to save the state our our tabs. Add this code to the file:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;- (void)applicationWillTerminate:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;	NSMutableArray *savedOrder = [NSMutableArray arrayWithCapacity:6];&lt;br /&gt;	NSArray *tabOrderToSave = tabController.viewControllers;&lt;br /&gt;	for (UIViewController *aViewController in tabOrderToSave) {&lt;br /&gt;		[savedOrder addObject:aViewController.title];&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	[[NSUserDefaults standardUserDefaults] setObject:savedOrder forKey:@&quot;savedTabOrder&quot;];&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;We create two arrays. One that holds the current list of view controllers called tabOrderToSave, and one that stores an array of strings that identify each of our controllers, savedOrder. When I created the view controllers I gave each of them a title. We'll use that title to identify the controllers when the application opens.&amp;nbsp;&lt;/p&gt;&lt;p&gt;You have to be careful here. If the title were being set during a viewWillAppear method for example, this would not work. The title would not be available. Another strategy would be to use a tag, or to explicitly store a property in the controller that could be used as an identifier. For this purpose, the title works fine.&lt;/p&gt;&lt;p&gt;The final line saves the array into the standard user defaults and gives it a key that we can use to recover it later.&lt;/p&gt;&lt;h3&gt;Restoring the Order of the Tabs in the Tab Bar Controller&lt;/h3&gt;&lt;p&gt;For this step, I'm going to add a helper method to the app delegate class.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Back in the TabBarSaveStateAppDelegate.h file, add this method to the interface.&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;- (void)setTabOrderIfSaved;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Then implement it in the implementation file:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;- (void)setTabOrderIfSaved {&lt;br /&gt;	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];&lt;br /&gt;	NSArray *savedOrder = [defaults arrayForKey:@&quot;savedTabOrder&quot;];&lt;br /&gt;	NSMutableArray *orderedTabs = [NSMutableArray arrayWithCapacity:6];&lt;br /&gt;&lt;br /&gt;	if ([savedOrder count] &amp;gt; 0 ) {&lt;br /&gt;		for (int i = 0; i &amp;lt; [savedOrder count]; i++){&lt;br /&gt;			for (UIViewController *aController in tabController.viewControllers) {&lt;br /&gt;				if ([aController.title isEqualToString:[savedOrder objectAtIndex:i]]) {&lt;br /&gt;					[orderedTabs addObject:aController];&lt;br /&gt;				}&lt;br /&gt;			}&lt;br /&gt;		}&lt;br /&gt;		tabController.viewControllers = orderedTabs;&lt;br /&gt;	}&lt;br /&gt;}&lt;/pre&gt;What's going on? First we get a reference to the standard user defaults. The second line restores the array that was saved when the application closed. Then we set up two loops. The outer loop goes through the saved order, and the inner loops checks the title of the controller against the string that was saved into the savedOrder array. When it gets a match, the controller is added to a new array. Finally, the new array is assigned to the tabController.viewControllers property. &lt;/li&gt;&lt;li&gt;To finish up, just call the new method before the tab controller is added to the window's subview.&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;...&lt;br /&gt;&lt;br /&gt;	[self setTabOrderIfSaved];&lt;br /&gt;&lt;br /&gt;	[window addSubview:tabController.view];&lt;br /&gt;&lt;br /&gt;    // Override point for customization after application launch&lt;br /&gt;    [window makeKeyAndVisible];&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;You should now be able to build and run the application. Reorder the tabs and close the application. When you open it the next time, they should be in the custom order.&lt;/p&gt;&lt;h3&gt;Using Interface Builder - Start With UITabBarController Project Template&lt;/h3&gt;&lt;p&gt;I did the same tasks using a interface builder. To create the project I used the UITabBarController project template. There were several differences.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Titles have to be set in Interface Builder. I gave each controller a title in interface builder by clicking on the tab in the MainWindow.xib file and entering the title in the in the title field view controller inspector.&lt;/li&gt;&lt;li&gt;The class for each controller has to be assigned in interface builder both in the main window file and in the second view file.&lt;/li&gt;&lt;li&gt;As I added tabs in interface builder, I set each tab to use the SecondView nib.&lt;/li&gt;&lt;li&gt;In the applicationWillTerminate: method I used the tabBarItem.title property for my identifier like this:&lt;br /&gt;&lt;pre class=&quot;code-box&quot;&gt;- (void)applicationWillTerminate:(UIApplication *)application {&lt;br /&gt;&lt;br /&gt;	NSMutableArray *savedOrder = [NSMutableArray arrayWithCapacity:6];&lt;br /&gt;	NSArray *tabOrderToSave = tabBarController.viewControllers;&lt;br /&gt;&lt;br /&gt;	for (UIViewController *aViewController in tabOrderToSave) {&lt;br /&gt;		[savedOrder addObject:aViewController.tabBarItem.title];&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	[[NSUserDefaults standardUserDefaults] setObject:savedOrder forKey:@&quot;savedTabOrder&quot;];&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Sample Xcode Projects&lt;/h3&gt;&lt;p&gt;Sample project: &lt;a title=&quot;Sample Project TabBarSaveState.zip&quot; href=&quot;/assets/51/TabBarSaveState.zip&quot;&gt;TabBarSaveState&lt;/a&gt; - The non-interface builder version&lt;/p&gt;&lt;p&gt;Sample project: &lt;a title=&quot;Sample Project TabBarSaveStateIB&quot; href=&quot;/assets/52/TabBarSaveStateIB.zip&quot;&gt;TabBarSaveStateIB&lt;/a&gt; - The interface builder version.&lt;/p&gt;</description>
          <pubDate>Fri, 27 Feb 2009 23:48:09 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-uitabbarcontroller-how-to-save-user-customized-tab-order/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-uitabbarcontroller-how-to-save-user-customized-tab-order/</link>
        </item>
    
        <item>
          <title>iPhone SDK: Creating a Modal Tab Bar Controller</title>
          <description>&lt;p&gt;In the Apple Developer Forum for iPhone SDK, I noticed a question about how to create a UITabBarController in a Modal View. Since I was curious, I decided to test it out. Here's my project, and the steps I took to create it.&lt;/p&gt;&lt;img src=&quot;/assets/43/groups-and-files.jpg&quot; style=&quot;float: left; margin: 0px 10px 10px 0px;&quot; alt='groups-and-files' /&gt;&lt;p&gt;Start by creating a new project in Xcode using the view based application project template, I called my project &quot;Modal_TabBar.&quot; Sorry, it's late, I couldn't come up with a better name. After the project is created, you'll have just a few files that should look something like the picture to the left. In this example we'll only need to edit three files. The Modal_TabBarViewController, both the header and the implementation file, and the NIB file Modal_TabBarViewController.xib.&lt;/p&gt;&lt;h3&gt;First the Header File&lt;/h3&gt;&lt;p&gt;The first thing we'll edit is the header file, Modal_TabBarViewController.h. Open it up and add the following code:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;&lt;br /&gt;@interface Modal_TabBarViewController : UIViewController {&lt;br /&gt;	UITabBarController *tbc;&lt;br /&gt;}&lt;br /&gt;- (IBAction)showModalTabBar;&lt;br /&gt;- (void)dismissTabBar;&lt;br /&gt;&lt;br /&gt;@property (nonatomic, retain) UITabBarController *tbc;&lt;br /&gt;@end&lt;/pre&gt;&lt;p&gt;I added a property to hold the actual tab bar controller so that I could release it when the modal view is dismissed. I also added two methods. One to show the modal tab bar, and one to dismiss it. The method to show the tab bar is defined as an IBAction so that I can link it up in Interface Builder. Which brings us to the next step.&lt;/p&gt;&lt;h3&gt;Link the Show Modal Method in Interface Builder&lt;/h3&gt;&lt;img src=&quot;/assets/44/IB-connections.jpg&quot; width=&quot;400px&quot; style=&quot;float: right; margin: 0px 0px 10px 10px;&quot; alt='IB-connections' /&gt;&lt;p&gt;Open the nib file that was created as part of the project template in the resources folder. In my case it is called Modal_TabBar View Controller.xib. Since my primary goal is to display a modal tab bar, I added a single button to the view and labeled it &quot;Show Modal Tab Bar.&quot; &lt;/p&gt;&lt;p&gt;Connect the button to the IBAction method in the controller by control dragging from the button to the Files Owner icon. Then select &quot;showModalTabBar&quot; when it pops up. See the illustration on the right. When done, return to Xcode.&lt;/p&gt;&lt;h3&gt;Complete the Implementation&lt;/h3&gt;&lt;p&gt;As you've probably guessed by now, we need to implement two methods to complete our simple project. Open the &quot;Modal_TabBarViewController.m&quot; file. At the top of the file, synthesize our property for the tab bar controller.&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;@synthesize tbc;&lt;/pre&gt;&lt;p&gt;Then implement the showModalTabBar method.&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;- (IBAction)showModalTabBar {&lt;br /&gt;&lt;br /&gt;	UIViewController *blueController = [[UIViewController alloc] initWithNibName:nil bundle:nil];&lt;br /&gt;	blueController.view.backgroundColor = [UIColor blueColor];&lt;br /&gt;	blueController.title = @&quot;Blue&quot;;&lt;br /&gt;&lt;br /&gt;	UIViewController *redController = [[UIViewController alloc] initWithNibName:nil bundle:nil];&lt;br /&gt;	redController.view.backgroundColor = [UIColor redColor];&lt;br /&gt;&lt;br /&gt;	UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];&lt;br /&gt;	[button setFrame:CGRectMake(20.0f, 140.0f, 280.0f, 40.0f)];&lt;br /&gt;	[button setTitle:@&quot;Done&quot; forState:UIControlStateNormal];&lt;br /&gt;	[button addTarget:self action:@selector(dismissTabBar) forControlEvents:UIControlEventTouchUpInside];&lt;br /&gt;&lt;br /&gt;	[redController.view addSubview:button];&lt;br /&gt;	redController.title = @&quot;Red&quot;;&lt;br /&gt;&lt;br /&gt;	tbc = [[UITabBarController alloc] initWithNibName:nil bundle:nil];&lt;br /&gt;	tbc.viewControllers = [NSArray arrayWithObjects:blueController, redController, nil];&lt;br /&gt;	tbc.selectedViewController = redController;&lt;br /&gt;	NSLog(@&quot;Selected index = %d of %d&quot;, tbc.selectedIndex, [tbc.viewControllers count]);&lt;br /&gt;&lt;br /&gt;	[blueController release];&lt;br /&gt;	[redController release];&lt;br /&gt;	[self presentModalViewController:tbc animated:YES];&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;We're adding two controllers to the tab bar controller. The first controller will be blue, and it will have a button on the tab bar with the title &quot;Blue.&quot; The second will be red, and it will have&amp;#160; a button on the tab bar with the title &quot;Red&quot; and a button in the middle of the screen labeled &quot;Done.&quot; When the done button is clicked, the modal controller will be dismissed.&lt;/p&gt;&lt;p&gt;First instantiate the two controllers and set the color and title properties. The title will be what gets displayed in the buttons of the tab bar. After instantiating the redController, create a button and add it as a subview. The line:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;[button addTarget:self action:@selector(dismissTabBar) forControlEvents:UIControlEventTouchUpInside];&lt;/pre&gt;&lt;p&gt;sets our dismissTabBar method so that it will be called when the button is clicked. Here's how to dismiss the modal controller after clicking the button.&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;- (void)dismissTabBar {&lt;br /&gt;	[self dismissModalViewControllerAnimated:YES];&lt;br /&gt;	[tbc release];&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Hey, that's it. You should be able to build and run your project. Click Show Modal Tab Bar button, click both tabs, and click the Done button in the Red tab. &lt;a href=&quot;/assets/45/Modal-TabBar.zip&quot;&gt;Download the project .zip file, about 1.4 MB.&lt;/a&gt; &lt;/p&gt;</description>
          <pubDate>Fri, 20 Feb 2009 08:47:11 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-creating-a-modal-tab-bar-controller/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/iphone-sdk-creating-a-modal-tab-bar-controller/</link>
        </item>
    
        <item>
          <title>Improving SEO With XML Site Mapping </title>
          <description>&lt;h3&gt;What's an XML Site Map&lt;/h3&gt;&lt;p&gt;If you're working on improving SEO for your website, or for one of your client's, you've probably had a need to create an XML site map. An XML site map is a file that lists the URLs in a website. It also allows you to include additional information about each URL, such as the date it was last updated, or how often it changes. &lt;/p&gt;&lt;p&gt;The XML site map is used to help crawlers find certain pages on your site. You can reference it in your robots.txt file or submit it directly to a search engine. Doing this does not ensure that the search engine will index your entire site. It is simply a guide to help the crawler find pages that it might otherwise miss.&lt;/p&gt;&lt;p&gt;Since we frequently use &lt;a title=&quot;Radiant CMS&quot; href=&quot;http://www.radiantcms.org&quot;&gt;Radiant CMS&lt;/a&gt;, I am going to describe the process of generating an XML site map in Radiant. I'll be formatting this for Google, which adheres to &lt;a href=&quot;http://www.google.com/webmasters/tools/protocol?hl=en&quot;&gt;Site map Protocol 0.9&lt;/a&gt; as defined by &lt;a href=&quot;http://www.sitemaps.org/&quot;&gt;sitemaps.org&lt;/a&gt;.&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;urlset xmlns=&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;&amp;gt;&lt;br /&gt;   &amp;lt;url&amp;gt;&lt;br /&gt;      &amp;lt;loc&amp;gt;http://www.example.com/&amp;lt;/loc&amp;gt;&lt;br /&gt;      &amp;lt;lastmod&amp;gt;2005-01-01&amp;lt;/lastmod&amp;gt;&lt;br /&gt;      &amp;lt;changefreq&amp;gt;monthly&amp;lt;/changefreq&amp;gt;&lt;br /&gt;      &amp;lt;priority&amp;gt;0.8&amp;lt;/priority&amp;gt;&lt;br /&gt;   &amp;lt;/url&amp;gt;&lt;br /&gt;&amp;lt;/urlset&amp;gt;&lt;/pre&gt;&lt;p&gt;Now that we know how the XML should look, and we know what it is for, let's get started. Luckily, Radiant makes this easy. &lt;/p&gt;&lt;h3&gt;Overview&lt;/h3&gt;&lt;p&gt;Here's the steps to complete our task.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create a new Layout that contains the basics of the XML document.&lt;/li&gt;&lt;li&gt;Create the Page that will generate the XML when it is requested.&lt;/li&gt;&lt;li&gt;Create Snippets of Radius code that will loop through the pages in the site and add the URLs to the page.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Creating a New Layout&lt;/h3&gt;&lt;p&gt;First things first, lets create the new Layout.&lt;/p&gt;&lt;p&gt;In your Radiant web site, click on the Layouts tab. If you already have a Layout called XML Feed, you're done. Just use it. If you don't, click on the Add Layout button. Name the Layout XML Feed, in the body enter the following:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;r:content /&amp;gt;&lt;/pre&gt;&lt;p&gt;This tells Radiant to include the content of the page in the Layout. In this case, that's all we need.&lt;/p&gt;&lt;h3&gt;Create a New Page for the XML Site Map&lt;/h3&gt;&lt;p&gt;Next, click on the Pages tab and create a new Page. In my case, I am making it a child of the home page, and I'm giving it the clever name, XML Site Map. Here's what should be in the page at this point:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;urlset xmlns=&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;&amp;gt;&lt;br /&gt;  --- Leave this area blank for now. We'll add code shortly.&lt;br /&gt;&amp;lt;/urlset&amp;gt;&lt;/pre&gt;&lt;p&gt;Be sure to select the XML Feed Layout when you save the Page.&lt;/p&gt;&lt;p&gt;There is a very good example of how to create an HTML site map on the &lt;a title=&quot;How to create a sitemap or menu in Radiant CMS&quot; href=&quot;http://radiantcms.org/blog/archives/2006/09/28/how-to-create-a-dynamic-sitemap-or-menu/&quot;&gt;Radiant Wiki&lt;/a&gt;. I'll be modifying details of that example from here on to create the XML site map. &lt;/p&gt;&lt;h3&gt;Create Snippets to do the Work&lt;/h3&gt;&lt;p&gt;Next create a Snippet that uses recursion to loop through all of the pages in the site. Click on the Snippets tab and click on the Add Snippets button. Enter the following code:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;r:children:each&amp;gt;&lt;br /&gt;  &amp;lt;r:unless_content part=&quot;no-map&quot;&amp;gt;&lt;br /&gt;    &amp;lt;url&amp;gt;&lt;br /&gt;      &amp;lt;loc&amp;gt;http://www.yoursite.com&amp;lt;r:url /&amp;gt;&amp;lt;/loc&amp;gt;&lt;br /&gt;      &amp;lt;lastmod&amp;gt;&amp;lt;r:date format=&quot;%Y-%m-%d&quot; /&amp;gt;&amp;lt;/lastmod&amp;gt;&lt;br /&gt;      &amp;lt;changefreq&amp;gt;monthly&amp;lt;/changefreq&amp;gt;&lt;br /&gt;      &amp;lt;priority&amp;gt;0.8&amp;lt;/priority&amp;gt;&lt;br /&gt;    &amp;lt;/url&amp;gt;&lt;br /&gt;    &amp;lt;r:snippet name=&quot;xml-sitemap&quot; /&amp;gt;&lt;br /&gt;  &amp;lt;/r:unless_content&amp;gt;&lt;br /&gt;&amp;lt;/r:children:each&amp;gt;&lt;/pre&gt;&lt;p&gt;Let's go ahead and complete the page to include the Snippet, and then come back for an explanation. Go back to the XML Site Map page we created earlier and modify it to look like this:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;urlset xmlns=&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;&amp;gt;&lt;br /&gt;  &amp;lt;r:find url=&quot;/&quot;&amp;gt;&lt;br /&gt;  &amp;lt;r:snippet name=&quot;xml-sitemap&quot; /&amp;gt;&lt;br /&gt;&amp;lt;/r:find&amp;gt;&lt;br /&gt;&amp;lt;/urlset&amp;gt;&lt;/pre&gt;&lt;h3&gt;What's Going On?&lt;/h3&gt;&lt;p&gt;I added two lines:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;r:find url=&quot;/&quot;&amp;gt;&lt;br /&gt;&amp;lt;r:snippet name=&quot;xml-sitemap&quot; /&amp;gt;&lt;/pre&gt;&lt;p&gt;This first line finds the root page in the site, and the second one loads the xml-site map Snippet.&lt;/p&gt;&lt;p&gt;The first line in the Snippet starts a loop that will go through each of the child pages in the site. Since we started with the root page, that means all of the pages. In this case, I don't actually want all of the pages. I want to skip my CSS and a couple of other pages that are not relevant for a site map.&lt;/p&gt;&lt;p&gt;The second line:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;r:unless_content part=&quot;no-map&quot;&amp;gt;&lt;/pre&gt;&lt;p&gt;does just that. In this case, for any page that I don't want included in the map, I've added a Page Part called no-map. To add a no-map Page Part, open any of your Pages and click on the green &quot;+&quot; icon to the right of the tabs. Name it no-map and click Add Part. You don't need to add anything to the Page Part. If the part is present, that page will be ignored in the site map.&lt;/p&gt;&lt;p&gt;The next lines generate the XML for each of the URLs:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;url&amp;gt;&lt;br /&gt;    &amp;lt;loc&amp;gt;http://www.raddonline.com&amp;lt;r:url /&amp;gt;&amp;lt;/loc&amp;gt;&lt;br /&gt;    &amp;lt;lastmod&amp;gt;&amp;lt;r:date format=&quot;%Y-%m-%d&quot; /&amp;gt;&amp;lt;/lastmod&amp;gt;&lt;br /&gt;    &amp;lt;changefreq&amp;gt;monthly&amp;lt;/changefreq&amp;gt;&lt;br /&gt;    &amp;lt;priority&amp;gt;0.8&amp;lt;/priority&amp;gt;&lt;br /&gt;&amp;lt;/url&amp;gt;&lt;/pre&gt;&lt;p&gt;This segment will be repeated for each page in the site. The &amp;lt;loc&amp;gt; tag contains the URLs. To match the date format in the sample XML, I added the format property to the date tag to get the date formatted as 2009-02-27. &lt;/p&gt;&lt;h3&gt;Refactor to Improve Frequency and Priority&lt;/h3&gt;&lt;p&gt;You've probably noticed that the change frequency and priority are a bit static. It is unlikely that they should be the same for every page. I'll take care of that next. &lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;&amp;lt;url&amp;gt;&lt;br /&gt;    &amp;lt;loc&amp;gt;http://www.raddonline.com&amp;lt;r:url /&amp;gt;&amp;lt;/loc&amp;gt;&lt;br /&gt;    &amp;lt;lastmod&amp;gt;&amp;lt;r:date format=&quot;%Y-%m-%d&quot; /&amp;gt;&amp;lt;/lastmod&amp;gt;&lt;br /&gt;      &amp;lt;r:if_content part=&quot;frequency-priority&quot;&amp;gt;&lt;br /&gt;        &amp;lt;r:content part=&quot;frequency-priority&quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/r:if_content&amp;gt;&lt;br /&gt;      &amp;lt;r:unless_content part=&quot;frequency-priority&quot;&amp;gt;&lt;br /&gt;        &amp;lt;changefreq&amp;gt;monthly&amp;lt;/changefreq&amp;gt;&lt;br /&gt;        &amp;lt;priority&amp;gt;0.8&amp;lt;/priority&amp;gt;&lt;br /&gt;      &amp;lt;/r:unless_content&amp;gt;&lt;br /&gt;&amp;lt;/url&amp;gt;&lt;/pre&gt;&lt;p&gt;This adds a check for a Page Part named frequency-priority. If it is present, it gets used. If not, it uses the default values from the original version. The last thing to do is to go to a page that should be different, and add a new Page Part named frequency-priority. The content of the Part should look like this:&lt;/p&gt;&lt;pre class=&quot;code-box&quot;&gt;      &amp;lt;changefreq&amp;gt;weekly&amp;lt;/changefreq&amp;gt;&lt;br /&gt;      &amp;lt;priority&amp;gt;0.9&amp;lt;/priority&amp;gt;&lt;/pre&gt;&lt;p&gt;Of course the values can be changed to whatever is relevant for that page. That's it. You should now have a page that returns an xml site map to help improve your SEO.&lt;/p&gt;</description>
          <pubDate>Fri, 13 Feb 2009 22:29:14 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/geek-journal/improving-seo-with-xml-site-mapping/</guid>
          <link>http://www.raddonline.com/blogs/geek-journal/improving-seo-with-xml-site-mapping/</link>
        </item>
    
    
    
    
        <item>
          <title>RaddOnline® awarded SF County Transportation Authority Project</title>
          <description>&lt;p&gt;We are delighted to announce that RaddOnline® will be working with &lt;a title=&quot;SFCTA.org&quot; href=&quot;http://www.sfcta.org/&quot;&gt;San Francisco County Transportation Authority&lt;/a&gt; on their Ruby on Rails website application development project.&amp;#160;&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;img src=&quot;/assets/196/sfcta_logo.jpg&quot;  alt='SFCTA Logo' /&gt;&lt;/center&gt;&lt;/p&gt;&lt;p&gt;About SFCTA&lt;/p&gt;&lt;p&gt;The San Francisco County Transportation Authority administers and oversees the delivery of the Proposition K (Prop K) half-cent local transportation sales tax program and New Expenditure Plan, which was passed by 75% of San Francisco voters in November 2003. The Authority was created in 1989 to administer Prop K's predecessor, the Proposition B half-cent transportation sales tax program, which began in 1990 and continued until it was superseded by Prop K.&lt;/p&gt;</description>
          <pubDate>Tue, 07 Jun 2011 19:03:41 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/raddonline-awarded-sf-county-transportation-authority-project/</guid>
          <link>http://www.raddonline.com/blogs/news/raddonline-awarded-sf-county-transportation-authority-project/</link>
        </item>
    
        <item>
          <title>Day 3 of Amazon's Troubles</title>
          <description>&lt;p&gt;We're now on the third day of trouble for Amazon Web Services and they are still reporting trouble. Well over 50 hours now puts them at at least 10 times their yearly downtime limits. Oh well, as a good friend of mine told me yesterday, &quot;whatayagunnado&quot;.&amp;#160;&lt;/p&gt;&lt;p&gt;Here's the latest status entry from Amazon.&lt;/p&gt;&lt;p&gt;9:11 PM PDT&amp;nbsp;We wanted to give a more detailed update on the state of our recovery. At this point, we have recovered a large number of the stuck volumes and are in the process of recovering the remainder. We have added significant storage capacity to the cluster, and storage capacity is no longer a bottleneck to recovery. Some portion of these volumes have lost the connection to their instance, and are waiting to be connected before normal operations can resume. In order to re-establish this connection, we need to allow the instances in the affected Availability Zone to access the EC2 control plane service. There are a large number of control plane requests being generated by the system as we re-introduce instances and volumes. The load on our control plane is higher than we anticipated. We are re-introducing these instances slowly in order to moderate the load on the control plane and prevent it from becoming overloaded and affecting other functions. We are currently investigating several avenues to unblock this bottleneck and significantly increase the rate at which we can restore control plane access to volumes and instances-- and move toward a full recovery.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The team has been completely focused on restoring access to all customers, and as such has not yet been able to focus on performing a complete post mortem. Once our customers have been taken care of and are fully back up and running, we will post a detailed account of what happened, along with the corrective actions we are undertaking to ensure this doesnt happen again. Once we have additional information on the progress that is being made, we will post additional updates.&lt;/p&gt;&lt;p&gt;Apr 23, 1:55 AM PDT&amp;nbsp;We are continuing to work on unblocking the bottleneck that is limiting the speed with which we can re-establish connections between volumes and their instances. We will continue to keep everyone updated as we have additional information.&lt;/p&gt;</description>
          <pubDate>Sat, 23 Apr 2011 15:44:02 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/day-3-of-amazons-troubles/</guid>
          <link>http://www.raddonline.com/blogs/news/day-3-of-amazons-troubles/</link>
        </item>
    
        <item>
          <title>Amazon EC2 and RDS Offline</title>
          <description>&lt;p&gt;Many of our sites are offline today because of an outage with Amazon's Elastic Compute Cloud service and their Relational Database Service. As well as our sites, major sites like Reddit, Foursquare, Quara, and Heroku are also offline.&lt;/p&gt;&lt;p&gt;Amazon says performance issues affected instances of its Elastic 
Compute Cloud (EC2) service and its Relational Database Service, and 
it’s “continuing to work towards full resolution”. These are hosted in 
its North Virginia data centre.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;1:48 AM PDT We are currently investigating connectivity and latency issues with RDS database instances in the US-EAST-1 region.&lt;br /&gt;
2:16 AM PDT We can confirm connectivity issues impacting RDS database 
instances across multiple availability zones in the US-EAST-1 region.&lt;br /&gt;
3:05 AM PDT We are continuing to see connectivity issues impacting some 
RDS database instances in multiple availability zones in the US-EAST-1 
region. Some Multi AZ failovers are taking longer than expected. We 
continue to work towards resolution.&lt;br /&gt;
4:03 AM PDT We are making progress on failovers for Multi AZ instances 
and restore access to them. This event is also impacting RDS instance 
creation times in a single Availability Zone. We continue to work 
towards the resolution.
&lt;br /&gt;&lt;span class=&quot;yellowfg&quot;&gt;8:54 AM PDT&lt;/span&gt;&amp;#160;We'd like to provide 
additional color on what were working on right now (please note that we 
always know more and understand issues better after we fully recover and
 dive deep into the post mortem).  A networking event early this morning
 triggered a large amount of re-mirroring of EBS volumes in US-EAST-1.  
This re-mirroring created a shortage of capacity in one of the US-EAST-1
 Availability Zones, which impacted new EBS volume creation as well as 
the pace with which we could re-mirror and recover affected EBS volumes.
  Additionally, one of our internal control planes for EBS has become 
inundated such that it's difficult to create new EBS volumes and EBS 
backed instances.  We are working as quickly as possible to add capacity
 to that one Availability Zone to speed up the re-mirroring, and working
 to restore the control plane issue.  We're starting to see progress on 
these efforts, but are not there yet.  We will continue to provide 
updates when we have them. &lt;/p&gt;&lt;/blockquote&gt;</description>
          <pubDate>Thu, 21 Apr 2011 16:51:03 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/amazon-ec2-and-rds-offline/</guid>
          <link>http://www.raddonline.com/blogs/news/amazon-ec2-and-rds-offline/</link>
        </item>
    
        <item>
          <title>GymRat version 1.1.2 is on iTunes app store!</title>
          <description>&lt;p&gt;New Update for GymRat for iPhone is out today that will take care of some bug fixes.&amp;#160; We've also enhanced the email feature so you can email your workouts or gym class information from within the application.&lt;/p&gt;&lt;p&gt;We want to take this opportunity to thank all our GymRat fans out there for using GymRat!&amp;nbsp;&amp;nbsp;&amp;nbsp; Special shout-outs to Jessie for helping us out with some bug fixes.&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p&gt; Be sure to update your app and let us know what you think either by writing a review on our iTunes application page OR by putting your comment in our special gymrat comments' area.&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p&gt;Be seeing you at the gym! &lt;/p&gt;</description>
          <pubDate>Tue, 22 Mar 2011 23:24:00 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/gymrat-version-1-1-2-is-on-itunes-app-store/</guid>
          <link>http://www.raddonline.com/blogs/news/gymrat-version-1-1-2-is-on-itunes-app-store/</link>
        </item>
    
        <item>
          <title>Now Available!  New version of GymRat for the iPhone, iPod Touch & iPad</title>
          <description>&lt;p&gt;GymRat Version 1.1.1 is now available on the App Store! &lt;a href=&quot;http://click.linksynergy.com/fs-bin/click?id=y5qwXHVpTVo&amp;amp;subid=&amp;amp;offerid=146261.1&amp;amp;type=10&amp;amp;tmpid=3909&amp;amp;RD_PARM1=http%3A%2F%2Fitunes.apple.com%2FWebObjects%2FMZStore.woa%2Fwa%2FviewSoftware%3Fid%3D311552669%2526mt%3D8&quot;&gt;Get it now!&lt;/a&gt; &lt;/p&gt;&lt;p&gt;GymRat is all about your workout success – how often you’ve worked out this week and how you improve over time. Dare to challenge yourself, your friends and workout buddies to top your best times. Share your favorite cardio, strength training, and interval and cross training workouts so everyone can feel the burn. You know you are stronger than most athletes. Personal trainers use GymRat to manage your clients’ workout profiles, details &amp;amp; results. Class Instructors can email your class or post your class information and updates to Facebook and keep your fans updated with latest 411! &lt;/p&gt;&lt;p&gt;For more information or a preview, check us out at &lt;a href=&quot;http://raddonline.com&quot;&gt;http://raddonline.com. &lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create custom workouts and log them&lt;/li&gt;&lt;li&gt;Choose from over 200 exercises or 
add more&amp;#160;&lt;/li&gt;&lt;li&gt;Share workouts and workout logs&lt;/li&gt;&lt;li&gt;Record times with the workout
 timer&lt;/li&gt;&lt;li&gt;Count down your time with the stop watch &lt;/li&gt;&lt;li&gt;Create multiple User 
profiles, each with workouts &amp;amp; logs&lt;/li&gt;&lt;li&gt;Track Gym Class schedules and 
instructors&lt;/li&gt;&lt;li&gt;Share your favorite Gym Classes with other GymRats &amp;amp; 
Facebook ...and more! &lt;/li&gt;&lt;/ul&gt;</description>
          <pubDate>Mon, 07 Feb 2011 19:51:35 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/now-available-new-version-of-gymrat-for-the-iphone-ipod-touch-ipad/</guid>
          <link>http://www.raddonline.com/blogs/news/now-available-new-version-of-gymrat-for-the-iphone-ipod-touch-ipad/</link>
        </item>
    
        <item>
          <title>BizConf 2010 August 3-6</title>
          <description>&lt;h3&gt;Who Should Attend&lt;/h3&gt;&lt;p&gt;It's simple: energetic, enthused folks who want to learn more about how
to actually do business today. This conference won't consist of
get-rich-quick talks or motivational speeches, but rather in-depth
presentations, discussions and workshops on how to communicate, manage
and network more dynamically and effectively.&lt;/p&gt;&lt;p&gt;Meet &lt;span class=&quot;attribute-value&quot;&gt;Obie Fernandez of HashRocket. Connect with other stars in the industry. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;../../../../reach-us&quot;&gt;Drop us line&lt;/a&gt; if you're going. Let's meetup. Or follow @ellenminer for conference updates.&lt;/p&gt;</description>
          <pubDate>Thu, 24 Jun 2010 19:38:14 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/bizconf-2010-august-3-6/</guid>
          <link>http://www.raddonline.com/blogs/news/bizconf-2010-august-3-6/</link>
        </item>
    
        <item>
          <title>Attending Agile Development Practices | West</title>
          <description>&lt;p&gt;&lt;img src=&quot;/assets/181/ADP_950_120_web_banner.gif&quot; width=&quot;400px&quot; alt='ADP banner' /&gt;&lt;/p&gt;


	&lt;p&gt;RaddOnline will be attending Agile Development Practices | West  this year and we&amp;#8217;d like to meet up with other companies/attendees. We&amp;#8217;re always on the lookout for new talent and new partnerships. If you will be attending &lt;span class=&quot;caps&quot;&gt;ADP&lt;/span&gt; West this year follow @ellenminer on Twitter for updates so you can find us. Or drop us a line or leave a comment!&lt;/p&gt;</description>
          <pubDate>Mon, 24 May 2010 19:35:15 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/attending-agile-development-practices-west/</guid>
          <link>http://www.raddonline.com/blogs/news/attending-agile-development-practices-west/</link>
        </item>
    
        <item>
          <title>GymRat for the iPhone is now on the Apple Store!</title>
          <description>&lt;p&gt;GymRat is now on the Apple Store.  &lt;a href=&quot;http://click.linksynergy.com/fs-bin/click?id=y5qwXHVpTVo&amp;subid=&amp;offerid=146261.1&amp;type=10&amp;tmpid=3909&amp;RD_PARM1=http%3A%2F%2Fitunes.apple.com%2FWebObjects%2FMZStore.woa%2Fwa%2FviewSoftware%3Fid%3D311552669%2526mt%3D8&quot;&gt;Get it now!&lt;/a&gt;

&lt;p&gt;GymRat is all about your workout success – how often you’ve worked out this week and how you improve over time. Dare to challenge yourself, your friends and workout buddies to top your best times. Share your favorite cardio, strength training, and interval and cross training workouts so everyone can feel the burn. You know you are stronger than most athletes.&lt;/p&gt;

&lt;p&gt;Personal trainers use GymRat to manage your clients’ workout profiles, details &amp; results.  Class Instructors can email your class or post your class information and updates to Facebook and keep your fans updated with latest 411! &lt;/p&gt;

For more information or a preview, check us out at &lt;a href=&quot;http://raddonline.com/products/gymrat/&quot;&gt;http://raddonline.com&lt;/a&gt;. &lt;/p&gt;&lt;br&gt;&lt;br&gt;


&lt;h4&gt;Features&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create custom workouts and log them
&lt;li&gt;Choose from over 200 exercises or add more
&lt;li&gt;Share workouts and workout logs
&lt;li&gt;Record times with the workout timer
&lt;li&gt;Count down your time with the stop watch
&lt;li&gt;Create multiple User profiles, each with workouts &amp; logs
&lt;li&gt;Track Gym Class schedules and instructors
&lt;li&gt;Share your favorite Gym Classes with other GymRats &amp; Facebook
&lt;/ul&gt;

...and more!</description>
          <pubDate>Fri, 01 May 2009 21:20:26 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/gymrat-for-the-iphone-is-now-on-the-apple-store/</guid>
          <link>http://www.raddonline.com/blogs/news/gymrat-for-the-iphone-is-now-on-the-apple-store/</link>
        </item>
    
        <item>
          <title>Now Available! New! GottaGet Version 1.3</title>
          <description>&lt;p&gt;Apple Computer approved the latest version of &lt;a title=&quot;Download Raddonline GotteGet for iPhone&quot; href=&quot;http://click.linksynergy.com/fs-bin/click?id=y5qwXHVpTVo&amp;amp;subid=&amp;amp;offerid=146261.1&amp;amp;type=10&amp;amp;tmpid=3909&amp;amp;RD_PARM1=http%3A%2F%2Fitunes.apple.com%2FWebObjects%2FMZStore.woa%2Fwa%2FviewSoftware%3Fid%3D300106156%2526mt%3D8&quot;&gt;GottaGet&lt;/a&gt; for the App Store. It is now available for download.&lt;/p&gt;


	&lt;h3&gt;What&amp;#8217;s New in this Version 1.3&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;Create and manage multiple lists&lt;/li&gt;
		&lt;li&gt;Categories that are empty no longer show in the GottaGet or Everything List&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You can now manage multiple lists, each consisting of a GottaGet list and an Everything list. You can create a special list for travel and swap the items onto the GottaGet list while you pack. Create as many lists as you need. Go to either the GottaGet or Everything list and click the Menu button. Then click Manage GottaGet Lists to add and edit lists.&lt;/p&gt;


	&lt;h3&gt;About GottaGet&lt;/h3&gt;


	&lt;p&gt;GottaGet is the iPhone / iPod Touch application by RaddOnline™. GottaGet is a free, versatile shopping list application for your iPhone that helps you remember the things you&amp;#8217;ve gotta get. The idea is simple. There are two lists, one with everything, and one containing only the things you&amp;#8217;ve gotta get. Add your grocery items, birthday gifts for your children, items from the hardware store or pharmacy, packing list for a trip, or anything you gotta get. Customizable categories make the possibilities endless. When you need an item, add it to the GottaGet list. When you get it, GottaGet puts the item back in the Everything List.&lt;/p&gt;


	&lt;p&gt;We started the Everything List for you by including a few items that we&amp;#8217;ve commonly GottaGet.  You can add any additional items you want!&lt;/p&gt;


Features include:
	&lt;ul&gt;
	&lt;li&gt;Create HoneyGet Email to email your GottaGet list &lt;/li&gt;
		&lt;li&gt;Option to show/hide the number of items in your GottaGet list on the icon badge&lt;/li&gt;
		&lt;li&gt;Ability to sort your lists by Name, Quantity or unit type&lt;/li&gt;
		&lt;li&gt;Option to pre-sort categories automatically or manually&lt;/li&gt;
		&lt;li&gt;Option to turn on/off sounds&lt;/li&gt;
		&lt;li&gt;Create multiple lists&lt;/li&gt;
	&lt;/ul&gt;</description>
          <pubDate>Tue, 28 Apr 2009 19:57:14 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/now-available-new-gottaget-version-1-3/</guid>
          <link>http://www.raddonline.com/blogs/news/now-available-new-gottaget-version-1-3/</link>
        </item>
    
        <item>
          <title>Lifehacking finds GottaGet "damn handy"</title>
          <description>&lt;p&gt;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;em&gt;[Note: this article was translated from Dutch and re-posted here in English from http://lifehacking.nl -- so some of the phrases may not totally translate well.] &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;A shopping list on your cell phone is not overly &quot;geeky&quot; and &quot;nerdy&quot;?&lt;/span&gt; &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;Perhaps, but I must say that &lt;a href=&quot;http://74.125.19.132/translate_c?hl=en&amp;amp;sl=nl&amp;amp;u=http://www.raddonline.com/products/GottaGet&amp;amp;prev=/search%3Fq%3Dlifehacking.nl%2Bgottaget%26hl%3Den%26rls%3Dcom.microsoft:*:IE-SearchBox%26rlz%3D1I7DKUS&amp;amp;usg=ALkJrhiYzS7aVqDOt2_x3q8m58l-bkoGRA&quot;&gt;GottaGet&lt;/a&gt; 
for iPhone is damn handy. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;Especially 
because I saw that light I have all sorts of scraps of writing what was, but 
also scraps invariably lost or at the supreme moment forgot to bring. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;And my phone, which I shall never forget. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;In addition I 
have a handy checklist of messages that I regularly need. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;Oh ja, de ketchup is op!&lt;/span&gt; Oh yes, 
the ketchup is on!&lt;/p&gt;&lt;p&gt;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;GottaGet is a simple application: you enter your 
messages once and can then continue to use.&lt;/span&gt;&amp;#160;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;What you need to get check in with a little with the finger ( &quot;Get 
it&quot;), you missed the message then tap on 'Got it'.&amp;nbsp;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt; Or you knew at once your whole shopping list.The application offers the 
possibility of numbers, units (bag, box, can) and a self-selected to each 
item. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;Use a 
dot: Create categories for corridors or areas in your favorite store. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;Number them according to the usual route through the 
store.&amp;nbsp;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;(See also the message on the &lt;a href=&quot;http://74.125.19.132/translate_c?hl=en&amp;amp;sl=nl&amp;amp;u=http://lifehacking.nl/thuis-tips/boodschappenplattegrond/&amp;amp;prev=/search%3Fq%3Dlifehacking.nl%2Bgottaget%26hl%3Den%26rls%3Dcom.microsoft:*:IE-SearchBox%26rlz%3D1I7DKUS&amp;amp;usg=ALkJrhh0xrfVfxWsJyyx-MjYasMpfAcmhg&quot;&gt;shopping 
map&lt;/a&gt; on this website.) In my supermarket to get past the first section of 
vegetables and fruit. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;In my list is so'01 Vegetables and Fruit '. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;That 01 is 
necessary because the program categories in alphabetical order without number 
sets.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;In practice a shopping list that I have 95% of what I do remember 
commitments.&lt;/span&gt; &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;Often, it means that I only just before the checkout even see my iPhone. Scheelde me that 
so far several times an extra trip to the supermarket. &lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt;Hooray! &lt;/p&gt;&lt;p&gt;&lt;span onmouseover=&quot;_tipon(this)&quot; onmouseout=&quot;_tipoff()&quot;&gt;&lt;/span&gt; Finally 
GottaGet also offers the possibility to list your e-mail, for example your 
partner or yourself, if you still like to make a PCB.&amp;nbsp;&amp;nbsp; &lt;a href=&quot;http://lifehacking.nl/thuis-tips/boodschappenlijstje-op-de-iphone/&quot;&gt;Check out the article in its original Dutch here!&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;</description>
          <pubDate>Mon, 27 Apr 2009 23:02:27 GMT</pubDate>
          <guid>http://www.raddonline.com/blogs/news/lifehacking-finds-gottaget-damn-handy/</guid>
          <link>http://www.raddonline.com/blogs/news/lifehacking-finds-gottaget-damn-handy/</link>
        </item>
    
    
  </channel>
</rss>


