Twitter REST API is very finicky

The post title says it all.

I have been trying to put together some code that calls the Twitter REST API, and found it to be extremely finicky. If you do not have everything just right, you will get back a frustrating error message that says “Could not authenticate you” and “code 32″. Not super helpful.

Most of the issues I had were in building the base string that gets sent to Twitter. If this string is not built exactly as it needs to be built, things will just not work.

Here is what I found about building the base string through trial and error, and with exhaustive searches of the Google and Stack Overflow:

  • After the endpoint URL, make sure that your query string parameters are in alphabetical order
  • If you are putting into the base string part of a query that needs to be URL encoded, then it needs to be double encoded inside the base string

For example, on this double encoding thing, if you want to search for “Twitter API”, the search part of your query string, once URL encoded would look like this:

%26q%3DTwitter%20API

However, you need to double encode the search text so that it looks like this instead:

%26q%3DTwitter%2520API

BTW, Happy Birthday to Brian May, guitarist from the legendary rock group Queen.

Swift (or in other words, “Et tu, Objective-C?”)

Well the WWDC keynote has come and gone. And what do you know, a developer conference keynote geared towards developers. I guess all those bloggers and press types that took up some of the WWDC tickets from us actual developers are pretty disappointed today, as there were no shiny new devices shown.

The big announcement in my opinion was Swift, which will be the successor to Objective-C for developing on the Mac and iOS platforms. It looks somewhat interesting, as yet again they have lowered the bar and made it much easier to develop software for their platforms. But this is a disadvantage as well as a strength, as folks will continue to churn out the clones and inferior products that clutter up the App Store.

I applaud Apple for creating Swift and not recycling an existing language such as Ruby, Python, or Javascript, as these languages all come with their own baggage. Hopefully I will not be throwing away the 6 years of experience that I have built up with Objective-C and they will allow it to be used for the foreseeable future.

Ah, I miss the days when retain/release separated the men from the boys in the iOS world…

There was some good news in the presentations from yesterday. In the Platforms State of the Union presentation, they indicated that the 100 device barrier for beta testing and internal testing will essentially be rendered moot through Apple’s integration of TestFlight. This feature can’t come soon enough for me, so please hurry up Apple.

BTW, so many birthdays today, not sure where to begin… Kerry King of Slayer (happy 50th), Ian Hunter most famously of Mott the Hoople, Chuck Barris of the Gong Show… But the name that jumps out for me is Tristan Rogers, currently portraying Colin on The Young And The Restless. Happy Birthday, mate!

resignFirstResponder does not put away keyboard on UIModalPresentationFormSheet

I started to use a few view controllers inside of navigation controllers that are presented with the UIModalPresentationFormSheet style, and to my dismay discovered that the resignFirstResponder call does not make the keyboard disappear.

Apparently there is a reason for this, if you are interested you can look it up and get a full explanation. For my purposes, I was just happy to discover that overriding the disablesAutomaticKeyboardDismissal method and returning NO seems to do the trick. Basically, now when I need to present a navigation controller in this fashion, I alloc the navigation controller with the class of MyNavigationController instead of UIViewController. Here is the code for MyNavigationController.m:

#import "MyNavigationController.h"
 
@implementation MyNavigationController
 
- (BOOL)shouldAutorotate
{
    return YES;
}
 
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}
 
- (BOOL)disablesAutomaticKeyboardDismissal
{
    return NO;
}
 
@end

You will of course need to change the rotation methods to your own needs.

Today, I have a double BTW for you. Happy birthday to Joe Bonamassa, one of my favorite guitar players and all around performers. And on a sad note, one year ago today, Jeanne Cooper, the grand old dame of The Young and The Restless, passed away. The show has not been the same without her.

Unable to simultaneously satisfy constraints

All of a sudden, I started getting this error popping up in the console while developing my iOS 7 app:

2014-04-30 11:32:27.199 MyApp[4495:60b] Unable to simultaneously satisfy constraints.
	Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; 
	(2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't
	understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x1946a510 h=-&- v=-&- DetailTableView:0xe39ce00.width == UIView:0x2613afd0.width - 293>",
    "<NSAutoresizingMaskLayoutConstraint:0x12ccfd50 h=--& v=-&- H:[UITransitionView:0x12ca7570(768)]>",
    "<NSAutoresizingMaskLayoutConstraint:0xcf18c40 h=-&- v=-&- UIView:0x2613afd0.width == ADTransitionView:0xcf16f20.width - 768>",
    "<NSAutoresizingMaskLayoutConstraint:0xcf19bb0 h=-&- v=-&- ADTransitionView:0xcf16f20.width == UITransitionView:0x12ca7570.width>"
)
 
Will attempt to recover by breaking constraint 
<NSAutoresizingMaskLayoutConstraint:0x1946a510 h=-&- v=-&- DetailTableView:0xe39ce00.width == UIView:0x2613afd0.width - 293>
 
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

A few notes about the app:

1. I am still a noob when it comes to Auto Layout, so I have been kind of easing into it on some of the less critical areas of the app, but the part of the app in question is still all springs and struts.
2. I am using the ADTransitionView library to do customized view controller transitions.
3. It did not do this until this morning.

If I hit continue a couple of times on the debug console, the app moves along as if there is no problem, so this is not a critical issue, but I still wanted to find out how to take care of this issue first, and then try to figure out what triggered it.

The way that I was able to get around the issue was to look at all of the nib files that make up my view controller, table view, and cells. I found that one of the component nib files was still flagged to use Auto Layout, even though there were no constraints of any kind in that nib file. When I turned off the Auto Layout flag on that file and ran the app, it started to transition between view controllers without the ‘Unable to simultaneously satisfy constraints’ message.

BTW, Happy Birthday to Phil “Scrap Iron” Garner, who was an infielder for the Pittsburgh Pirates in the late 70′s and early 80′s.

Windows 8.1 Update 1 error 80073712

It can be very frustrating when you end up searching for help with a Windows Update issue. There are so many moving parts on a Windows system that it is next to impossible to track everything reliably.

While trying to put the Windows 8.1 Update 1 on my Windows 8 virtual machine inside of Parallels Desktop on my iMac, I was getting error 80073712 in the update settings control panel. There is no shortage of materials to look at if you search for that particular error code, the tricky part is finding which one will help solve the particular problem with my installation.

I was finally able to find this procedure, and it did the job as I am now running Windows 8.1 Update 1. I will abbreviate it here, for the full source material click on the link below the list:

  • Get an administrator command prompt
  • Enter this command (I am running the 64 bit version, you will need a different command to work with 32-bit or Win 8 RT, see the link for more information):
    dism /online /remove-package /packagename:Package_for_KB2919355~31bf3856ad364e35~amd64~~6.3.1.14
  • Enter this command:
    DISM.exe /Online /Cleanup-image /Restorehealth
  • Enter this command:
    dism /online /cleanup-image /startcomponentcleanup
  • Exit the command prompt and attempt to run the update again

Even though the 2nd command above gave me an error, I went through the whole procedure, and it worked correctly. Here is the link to the forum posting on Microsoft’s web site with the full message:

Windows 8.1 Update 1 Failing to Install with errors 80070020, 80073712 and 0x800f081f

BTW, a posthumous Happy Birthday to Bruno Kirby, who played the limo driver in This Is Spinal Tap.

NSString to UIImage

I had the need to take a regular old NSString and get a UIImage representation of that text. It seems like a relatively straightforward thing to do, so here is the code that I put together:

+ (UIImage *)imageWithView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}
 
+ (UIImage *)imageWithString:(NSString *)theString font:(UIFont *)theFont color:(UIColor *)theColor
{
    UILabel *tempLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    tempLabel.backgroundColor = [UIColor clearColor];
    tempLabel.textColor = theColor;
    tempLabel.font = theFont;
    tempLabel.text = theString;
    [tempLabel sizeToFit];
 
    return [self imageWithView:tempLabel];
}

As an added bonus, if you happen to be using Font Awesome in your iOS project (and let’s be honest, if you aren’t, you should be), here is a bonus method:

+ (UIImage *)imageWithFontAwesomeIcon:(NSString *)faIcon fontSize:(CGFloat)fontSize color:(UIColor *)fontColor
{
    return [self imageWithString:[NSString fontAwesomeIconStringForIconIdentifier:faIcon]
                            font:[UIFont fontWithName:kFontAwesomeFamilyName size:fontSize]
                           color:fontColor];
}

BTW, Happy Birthday to Brian Setzer, who is a fantastic guitar player and singer.

UITextView font in IB not respected

One thing that I found to be a bit odd is that, with the latest Xcode 5 and iOS 7 SDK, if you create a UITextView inside of a UITableViewCell in Interface Builder, and change the font of the text view, it will not use your changed font in the simulator or on a device. After checking with Stack Overflow, I found that if I ticked the Selectable property for my UITextView, all of a sudden it started to respect the new font that I had selected. I am not sure if that is a bug or by design, anyone have any ideas or cite documentation one way or the other?

BTW, Happy Birthday to Leonard Nimoy. Live long and prosper.

Use NIB-based UITableViewCell properly

I like to create my complex UITableViewCell objects in their own NIB files, as it helps me keep things well organized. Unfortunately, I felt like I was not able to use NIB-based UITableViewCell properly, as the implementation of this was always a bit clunky in my opinion, since I was relegated to doing something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"CellIdentifier";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    {
        [[NSBundle mainBundle] loadNibNamed:@"MyCustomCell" owner:self options:NULL];
        cell = myCustomCell;
        self.myCustomCell = nil;
    }
 
    // do something here with the cell
 
    return cell;
}

Ugh, this was a bit messy. You had to make sure that your MyCustomCell.xib file had the file’s owner pointing back to your view controller class, and that you set up an IBOutlet to the cell.

The ability to take a project and require the latest version of iOS can be a refreshing thing, as it allows one to come up to the latest APIs and practices without having to maintain painful backward compatibility. Just such a thing happened today as I learned about the proper way to use a UITableViewCell from a NIB file.

This process involves registering a class or NIB file to work with a UITableView, hooked in through the cell identifier. To set up this registration, you would do something like this in your viewDidLoad method:

UINib *nib = [UINib nibWithNibName:@"MyCustomCell" bundle:nil];
[_theTableView registerNib:nib forCellReuseIdentifier:CellIdentifier];

(Just make sure to set up your CellIdentifier NSString variable as a global in the class or as a static in the same area that you register the NIB.) And then, the cellForRowAtIndexPath method has a little less heft to it:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 
    // do something here with the cell
 
    return cell;
}

Because you have registered the NIB file with the cell identifier on your table view, the dequeueReusableCellWithIdentifier method knows how to either reuse or create a cell without having to explicitly do it in code. I like less heft.

BTW, Happy St. Patrick’s Day to everyone, Irish and non-Irish alike. Please be safe out there and don’t do anything dumb, which is actually a good rule to live by the other 364.24 days of the year as well.

Core Data error: The operation couldn’t be completed. (Cocoa error 19.)

Well, it has been over a year since I last had a customer with a corrupted database problem. Which means that I guess I was overdue. And what problem it is.

My customer is reporting that they now get the following error on their iPad when they try to do something with their database:

cocoa_error_19

Just in case you can’t read the text in the photo, it says:

The operation couldn’t be completed. (Cocoa error 19).

After some trouble getting the file (it is over 4 GB, not easy to e-mail), I saw a bunch of errors pop up in my debug console, including the dreaded “The database disk image is malformed”, which to me indicated that I needed to try and repair the database file. So I punched up my blog post from February of last year to try and run a repair on it.

Unfortunately, I ran into one dead end after another. I was able to dump the data out of the original database file, which produced a text file of over 8 GB. However, no matter what I tried to do to import this data back into a new database, I would end up with an empty new database.

On a lark, I decided to switch to Windows to try and fix the database file. After downloading the tools from the SQLite web site, Here is what I ended up with on my Windows computer:

C:\database>dir
 Volume in drive C is Windows7_OS
 Volume Serial Number is 50B0-39AA
 
 Directory of C:\database
 
03/14/2014  06:27 PM    <DIR>          .
03/14/2014  06:27 PM    <DIR>          ..
03/14/2014  06:16 PM     4,251,181,056 DB.sqlite
03/11/2014  11:33 AM           536,064 sqlite3.exe
03/11/2014  11:34 AM         1,388,032 sqlite3_analyzer.exe
               3 File(s)  4,253,105,152 bytes
               2 Dir(s)  240,466,235,392 bytes free

So I fired up a command prompt and tried to run some SQLite commands:

C:\database>sqlite3
SQLite version 3.8.4.1 2014-03-11 15:27:36
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open DB.sqlite
sqlite> .tables
.
.
Some table names listed here
.
.
sqlite> pragma integrity_check;
*** in database main ***
On tree page 1033353 cell 0: Failed to read ptrmap key=-280958431
On tree page 1033353 cell 0: 152 of 407 pages missing from overflow list starting at 1037333
Page 1037588 is never used
Page 1037589 is never used
.
.
You get the idea...
.
.
Page 1037684 is never used
Page 1037685 is never used

After going through the series of steps that I outlined in my message from last year, it appeared to process the 8 GB text file into a new database that was almost the same size as the original database file. Here was what my directory then looked like:

C:\database>dir
 Volume in drive C is Windows7_OS
 Volume Serial Number is 50B0-39AA
 
 Directory of C:\database
 
03/14/2014  06:45 PM    <DIR>          .
03/14/2014  06:45 PM    <DIR>          ..
03/14/2014  06:41 PM     8,428,761,778 dump_all.sql
03/14/2014  06:16 PM     4,251,181,056 DB.sqlite
03/14/2014  06:45 PM     4,239,932,416 DB2.sqlite
03/11/2014  11:33 AM           536,064 sqlite3.exe
03/11/2014  11:34 AM         1,388,032 sqlite3_analyzer.exe
               5 File(s) 16,921,799,346 bytes
               2 Dir(s)  227,795,791,872 bytes free

This had me feeling pretty good. Just to check, here is what I did next:

C:\database>sqlite3 DB2.sqlite
SQLite version 3.8.4.1 2014-03-11 15:27:36
Enter ".help" for usage hints.
sqlite> .tables
.
.
Some table names listed here
.
.
sqlite> select count(*) from table_name;
8716
sqlite> pragma integrity_check;
ok
sqlite> vacuum;
sqlite> .exit

It looks like success. I will have to take this data file and put it back on one of my test iPads when I get back into the office and try it out.

BTW, Happy Pi Day to everyone out there, whether you are a math person or not.

ADDENDUM: After putting the rebuilt SQLite database file back onto my own test iPad and simulator, it worked fine with no issues or cryptic error messages.

UIPopoverController arrow displays incorrectly on iOS 7

This one still doesn’t make sense to me, but I need to put it to bed and move on. When retooling an app for the latest iOS SDK, the UIPopoverController arrow displays incorrectly on iOS 7 in certain instances.

In the case where I need to display a popover controller as the result of the user tapping on a cell in a UITableView, this code has always worked fine in my iPad applications:

[thePopover presentPopoverFromRect:cell.frame inView:theTable permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];

However, after I switched over to using the iOS 7 SDK, the results look like this now:

popover_arrow_incorrect

After a bunch of investigations, I decided to try this just for the heck of it:

CGRect rect = CGRectMake(CGRectGetMaxX(cell.bounds) * 0.9, CGRectGetMidY(cell.bounds), 1.0, 1.0);
[thePopover presentPopoverFromRect:rect inView:cell permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];

With this code change, it now it looks like this:

popover_arrow_correct

And I am happy once again. Although I would still like to know why the original code does not work, if anyone has any ideas please feel free to comment. As you can see from the first image, the popover is positioned correctly (notice the vertical placement of the two line table view inside the popover, it is showing the same in both examples), it is just the arrow that is drawn incorrectly.

BTW, Happy Birthday to Tim Kazurinsky, who was great in his all-too-brief stint on Saturday Night Live, and utterly fantastic in the Police Academy series of films.