Expired Provisioning Profiles — Why Won’t My App Run/Debug?

This post answers the following questions:

  1. Why won’t my app run or debug?
  2. What do I do with “The application cannot be opened because the provisioning profile has expired?”
  3. I’m getting “The program being debugged is not being run” — help!
  4. What does, “Error from Debugger : The program being debugged is not being run” mean?

We were modifying an older application for a client today, and Xcode simply would not let us debug on our iPad.  Xcode was telling us, “”Error from Debugger : The program being debugged is not being run.”  Great.  Care to tell us why?

After looking around for a bit, we tried running the app on the device by pressing the springboard icon rather than Build & Go from Xcode, and were confronted with a different error: “The application cannot be opened because the provisioning profile has expired.”  Ok, that’s a little more clear, but we’re still in Apple code signing hell, which any iPhone developer knows can eat up hours of time.

Uninstalling the app and re-installing did not help, Clean All Targets didn’t help, and adjusting the code signing on both the project and the active target did nothing — both were set to use our automatically provisioned profile.  We updated our automatically provisioned profile a few weeks ago to replace an expiring one, so I knew that the profile was valid.  But, I checked it out anyway, and saw a screen much like this:

This screen can be found by bringing up Organizer while your device is plugged in, and then clicking on your device.  What appears to have happened is that even though our new provisioning profile was downloaded by the development machine, and even though that profile was distributed to this iPad, the old profile remained and was being used by default.

Lame, but a quick solution: remove the profile with the X.  For good measure, we uninstalled the app from the iPad and Cleaned All Targets, and then Build and Run ran as it should.  I hope this helps (though by the time you’ve found this, you’ve probably already wasted at least half an hour trying to figure it out!).

FourTen Technologies, Inc., is a leading US iPhone app development firm. For information on having FourTen build a custom mobile application for your company, visit www.fourtentech.com. Article written by Jonathan Corbett (President & CEO, FourTen). Contact: jcorbett@fourtentech.com.

Getting Data from Web Services — The Easy Way

This post answers the following questions:

  1. Do I need to use XML to transfer data from a Web service?
  2. How can I get data from PHP to my app?
  3. How can I send data to a script on a Web server — without XML?

Many times we get project specs from our clients that call for XML to transfer data between a Web service of some sort (be it PHP, .NET, or something else), and most of the time, the amount and complexity of data being returned is minimal. When this is the case, we generally advise against using the beloved XML for the transfer.

“That’s blasphemy,” you say? No, it’s actually a compliment to XML. As it is able to handle large and complex data operations, it simply contains a bunch of “stuff” that we don’t need, and implementing a parser takes development time, which costs you money, and processor time, which costs your app’s response time.

The most common data transferred back and forth is a user account. Username, password, e-mail, and maybe a few other fields specific to the application. We could put those fields in an XML file and POST it back to a Web service:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<Register>
<user>410Technologies</user>
<pass>********</pass>
<email>sales@fourtentech.com</email>
</Register>

…and waste all the overhead required to build and store that string (both CPU/memory overhead and coding time overhead) and transmit it over the air, or we could simply call the Web service via GET, like so:

?user=410Technologies&pass=********&email=sales%40fourtentech%20com

Note that neither method is more or less secure: both can be done over HTTPS, if you’d like.  Similarly, when we get data back, we can use a similar technique. A typical login command might return the user’s first name (to welcome them, of course), an account status, and an account balance. We could do that with XML:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<Login>
<firstname>Max</firstname>
<status>1</status>
<balance>$4.10</balance>
</Login>

…or we can pick a delimiter and send the three fields without any fancy encoding. If you’re returning a field that was input by a user on an iPhone, the tab character (‘\r’) makes a great delimiter, since there’s no way a user can type a tab using the iPhone. We code our Web service to return a string that looks like this:

Max\r1\r\$4.10

…and can load that into an array quickly and easily using the componentsSeparatedByString: function:

NSArray *user = [[NSArray alloc] initWithArray:[[NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://clients.fourtentech.com/sample/web/service.aspx"]] componentsSeparatedByString:@"\r"]]

…saving about 80% of the bandwidth, avoiding implementing a resource-intensive parser, and remembering to release our object when we’re done, of course.

If you’re developing large, complex data transfers, or transfers that may become that way, XML is your friend. When that’s not the case, we keep it simple and respect that on a tiny device with an often-slow connection, we should conserve as many resources as possible, as well as conserving our client’s financial resources whenever possible as well (we’d much rather sell you useful features and add-ons rather than “technicalities” like unnecessary XML implementations!).

FourTen Technologies, Inc., is a leading US iPhone app development firm. For information on having FourTen build a custom mobile application for your company, visit www.fourtentech.com. Article written by Max Whitman (Lead Developer, FourTen). Contact: mwhitman@fourtentech.com.

Tables, Part III — Re-Ordering / Moving Cells and “Swipe to Delete!”

This post answers the following questions:

  1. How do I add re-order grips to my UITableViewCells?
  2. What do I do to allow users to remove cells from a UITableView?
  3. How can I implement swipe-to-delete?

In Part II, we covered adding some custom elements to your tables.  If you want to allow users to edit the contents of a cell, a common way of doing that is, once the user pushes an “Edit” button, to simply add a UITextField to your cell in the place of where you normally put, say, a UILabel.  The code from Part II should be able to get you through this.

But!  The UITableView offers some cool built-in features for moving and deleting cells that will give your app a more consistent “iPhone feel” than if you were to custom-implement them yourself, and may save you some time as well.

Starting with our code from the previous tutorial, we’re going to add a member variable to our view controller class header:

NSMutableArray *aCellText;

…and in our viewDidLoad: function, we’ll initialize the array with three objects:

aCellText = [[NSMutableArray alloc] initWithObjects:@"For mobile application", @"development, visit:", @"www.fourtentech.com", nil];

…and don’t forget to release the array when you’re done with it.  Then, in cellForRowAtIndexPath:, change this line:

l.text = [NSString stringWithFormat:@"cell %i", indexPath.row];

…to this one:

l.text = [aCellText objectAtIndex:indexPath.row];

Lastly, comment out the UIButton immediately below the line we just added, Build & Go, and you should see something like this:

Our table’s contents is now dynamically generated from an array.  Now that we have some dynamic content, we can begin to edit it.  Add the following line to your viewDidLoad: function:

tvMain.editing = YES;

…as well as these two delegate methods:

- (BOOL)tableView:(UItableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
  return YES;
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
  NSObject *o = [aCellText objectAtIndex:sourceIndexPath.row];

  if(destinationIndexPath.row > sourceIndexPath.row) //moving a row down
    for(int x = destinationIndexPath.row; x > sourceIndexPath.row; x--)
      [aCellText replaceObjectAtIndex:x-1 withObject:[aCellText objectAtIndex:x]];
  else //moving a row up
    for(int x = destinationIndexPath.row; x < sourceIndexPath.row; x++)
      [aCellText replaceObjectAtIndex:x+1 withObject:[aCellText objectAtIndex:x]];

  [aCellText replaceObjectAtIndex:destinationIndexPath.row withObject:o];

  [tvMain reloadData];
}

…and you should get the following after Bulid & Go:

We’ve done a lot here — let’s take a step back.  The first thing we did was to turn on “editing mode” on the UITableView.  Normally, you wouldn’t do this in viewDidLoad:, but rather as a response to a user button press — though for tutorial purposes, this works.

We then added two delegate methods, the first of which is self-explanatory and needs no further commentary, but the second of which is more important.  When a user drags a cell from one position to the other using the reorder grips shown in the image, the UI updates, but you also need to update your data storage (in this case, an NSMutableArray) to reflect the change.  The code here detects if you’re trying to move a cell upwards or downwards, and then shifts all the cells between your original position and the desired position up or down to accommodate the change.  We then reload the table data to ensure that the view contiunes to display properly.

This also provides you a button to delete a cell, but 1) we haven’t yet implemented the code to handle the data store change on deletion, and 2) swipe to delete is way cooler than showing a delete button on every cell.  We’ll do both below.

Start by commenting out the tvMain.editing line that we put in earlier to get rid of the grips and delete buttons.  We’re then going to let the UITableView know that the number of rows may actually change by updating the contents of numberOfRowsInSection: to read:

return [aCellText count];

Then, we’re going to implement the following delegate method:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
  if(editingStyle == UITableViewCellEditingStyleDelete) {
    [aCellText removeObjectAtIndex:indexPath.row];
    [tvMain reloadData];
  }
}

When this delegate method is defined, the iPhone will allow swipe-to-delete with no further action necessary!  A rebuild and a swipe on the middle row will get us:

This is the last of a three-part series on the UITableView — we hope it’s been useful!

FourTen Technologies, Inc., is a leading US iPhone app development firm. For information on having FourTen build a custom mobile application for your company, visit www.fourtentech.com. Article written by Andre Chambers (Chief Technology Officer, FourTen). Contact: achambers@fourtentech.com.



Tables, Part II — Customizations (“Putting Stuff In Your Cells”)

This post answers the following questions:

  1. How do I put stuff in my table?
  2. What do I do to add images to a UITableView / UITableViewCell?
  3. Can I put a button inside a table cell?

The UITableViewCell comes with many ways to format the content within them.  But really, I don’t particularly care for using them.  Since you can simply add any UIView subclass as a subview of a UITableViewCell, I feel that using the built-in cell formatting techniques are limiting (with the exception of editable cells, which we’ll discuss in the next post), and most of our clients want their tables to do “moar.”

Start by creating a project with a UITableView just as we did in the previous tutorial, except make this one a “plain” table instead of a grouped table.  Set the number of sections to 1, the number of rows per section to 3, and the height of every row to be 75.0.  Also, add a 57x57px .png file to the project named “fourtentech.png” — any .png will do. 

We’re going to adjust our cellForRowAtIndexPath: function to look like this:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, 320, 75) reuseIdentifier:@"thecell"] autorelease];
 cell.backgroundColor = [UIColor whiteColor];
 
 UIImageView *i = [[[UIImageView alloc] initWithFrame:CGRectMake(11, 11, 57, 57)] autorelease];
 i.image = [UIImage imageNamed:@"fourtentech.png"];
 [cell addSubview:i];
 
 UILabel *l = [[[UILabel alloc] initWithFrame:CGRectMake(65, 11, 229, 24)] autorelease];
 l.text = [NSString stringWithFormat:@"cell %i of section %i",indexPath.row,indexPath.section];
 l.font = [UIFont boldSystemFontOfSize:18];
 [cell addSubview:l];
 
 UIButton *b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
 b.frame = CGRectMake(250, 10, 60, 55);
 [b addTarget:self action:@selector(dontTouchMe:) forControlEvents:UIControlEventTouchUpInside];
 [b setTitle:@"Press Me!" forState:UIControlStateNormal];
 b.buttonType = UIButtonTypeRoundRect;
 b.tag = indexPath.row;
 [cell addSubview:b];
 
 return cell;
}

Build and Run, and you should now have:

We’ve added to the UITableViewCell an image, a label, and a button.  The frame specified in the CGRectMake is relative to the UITableViewCell (as it would have to be — otherwise your cell content wouldn’t move when the table did!).  Also, the frame that you give to the UITableViewCell, in this and many circumstances, doesn’t even need to be exact.  If it’s too small, your subviews can exceed the bounds of the cell (up to the height of the cell specified by the UITableView), and if it’s too big, it will be clipped by the UITableView.  In other words, if some of your cells are 40px high and others are 50px high, just set the UITableViewCell height to be 50px and don’t worry about it — everything will display just fine.

The only truly interesting thing about the above code is tagging the button.  The problem we’d encounter without tags is that when the button is pressed, our dontTouchMe: event handler would have no idea which of the three buttons was pressed.  We could set each button to have a different title and have our event handler check which title the event-sending button has, but maybe we want all the buttons to have the same title. Tagging allows us to assign an integer to the button for later reference, and is completely transparent to the user. Since we only have one section, we simply need to know the row number.

Create your dontTouchMe: function like the one below:

- (void)dontTouchMe:(id)sender {
 NSLog(@"Touched Button %i",((UIButton *)sender).tag);
}

…which will log to console which button was pressed.  Build & Debug in Xcode, and push Command-Shift-R to bring up the console.  Then, when pressing a button (the first button, for example), you’ll see output:

Note that touching the button and touching the rest of the cell are now completely different events, and can be coded to do completely different things.

This is a three-part series on the UITableView — please check back for more if you’re looking to go deeper.

FourTen Technologies, Inc., is a leading US iPhone app development firm. For information on having FourTen build a custom mobile application for your company, visit www.fourtentech.com. Article written by Andre Chambers (Chief Technology Officer, FourTen). Contact: achambers@fourtentech.com.



Tables, Part I — How To Use Basic UITableViews

This post answers the following questions:

  1. How do I implement a basic table (UITableView) in my iPhone app?
  2. What do I do to respond when a user presses a table cell?
  3. I need to customize the contents of a UITableViewCell — help?!

The UITableView is one of the most well-recognized of the built-in components for iPhone.  There are two main styles of table: grouped and plain.  Grouped tables are typically used to show small amounts of data in a pretty, orderly layout.  Plain tables are better suited to larger datasets because of more efficient use of space and the ability to add an index on the right side to jump to a letter.  They are also better suited to completely custom cells.

 
Grouped Table
 
Plain Table

We’ll start with the grouped table in Part I.  Either drag a UITableView onto your view in Interface Builder (IB) and select Grouped from View Attributes (press Command-1 if you don’t see it), or you can put it into your app via code:

UITableView *tv = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStyleGrouped];
tv.delegate = self;
tv.dataSource = self;

If you add your table via code, don’t forget to release the object when you’re done with it.  If you add your UITableView using IB, you’ll need to create an outlet in code and set the delegate and data source in IB:

IBOutlet UITableView *tv;

…then right drag from File’s Owner in IB to the Web view to set the outlet, and right drag the reverse direction to set the delegate and data source.  What this does is it tells the SDK that the class that’s going to handle populating the table as well as dealing with table events is the current one.  Should this be a default?  Of course, but it’s not.  You’ll also need to designate your class as conforming to the relevant protocols.  In your .h, immediately after it says UIViewController (before the brace), add in <UITableViewDelegate,UITableViewDataSource>

You’ve now got the basics down, but table views require five functions to be implemented.  The first we’ll implement as follows:

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

So far, not to difficult.  In fact, I’m not sure this one needs any further explanation.  Moving along to our second:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  if(section == 0)
    return 2;

  return 3;
}

Also relatively straight forward.  The first section will have 2 rows, while all other sections will have 3.  Often times, you’ll be populating tables out of arrays, and so you’ll be returning [array count] instead of a constant.  Continuing…

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  if(indexPath.section == 0 && indexPath.row == 0)
    return 75.0;

  return 50.0;
}

The height in pixels for a given row.    Rows are identified by an indexPath, which is an object that has two relevant member variables: a section number and a row number.  The effect of the above code is that the first cell in the first section (numbering starts at 0, of course) will be 50% larger than all other rows.

Next is the most important: the code that generates the contents of your cells.  Each cell in your table is a UITableViewCell object, which in turn is a UIView object.  This means that you can simply add other objects as subviews of it:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0,0,300,75) reuseIdentifier:@"thecell"] autorelease];
  cell.backgroundColor = [UIColor whiteColor];

  UILabel *l = [[[UILabel alloc] initWithFrame:CGRectMake(18,11,229,24)] autorelease];
  l.text = [NSString stringWithFormat:@"cell %i of section %i",indexPath.row,indexPath.section];
  [cell addSubview:l];

  return cell;
}

The last thing required is code to handle what happens when a user touches a cell.  This code is required, even if you want to take no action (simply deselect the row and return).

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Before you return, you’re free to check your indexPath.section and indexPath.row and take an action before deselection.  Deselection is required, and failure to do so may result in App Store rejection.  You now should get a table that looks like this:

This is a three-part series on the UITableView — please check back for more if you’re looking to go deeper.

FourTen Technologies, Inc., is a leading US iPhone app development firm. For information on having FourTen build a custom mobile application for your company, visit www.fourtentech.com. Article written by Andre Chambers (Chief Technology Officer, FourTen). Contact: achambers@fourtentech.com.