Two Shots Of Cocoa
31Mar/130

UIView color pattern image from Interface Builder

Here's another quick trick to avoid having to create IBOutlets to set properties.
As I mentioned in a previous post, you can define any attribute for an object right from IB.
But pattern image is not an attribute of UIView.

Well I made it a category and called it a day! And this can be done for anything that you need post nib loading!

The runtime attribute would look like this:

and category method looks something like this:

1
2
3
- (void)setColorPattern:(NSString*)patternImageName {
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:patternImageName]];
}
20Aug/120

Simpler nib loading for UIViewController

I was so tired of always doing

1
MyCustomViewController *custom = [[MyCustomViewController alloc] initWithNibName:@"MyCustomViewController" bundle:nil];

that I made a category to minimize it to:

1
MyCustomViewController *custom = [MyCustomViewController initWithNib];

Enjoy!

 

1
2
3
4
5
+ (id)initWithNib {

return [[self alloc] initWithNibName:NSStringFromClass(self) bundle:nil];

}
18Aug/120

Interface Builder’s User Defined Runtime Attributes

If you are like me you use Interface Builder to do super fast prototyping and development for views with a static layout/design or even for views with a dynamic one.
If you are like me you also subclass the hell out of UIKit classes to make you own awesome things.

The problem though, is that these awesome subclasses don't work that nicely with Interface Builder.
If you subclass UITextView, for example, to allow having some placeholder text, in interface builder you get all the goodies from UITextView but not the awesome things from your class.
At least that is what I thought, until now.

You can define your subclass' attributes right from IB!
It supports the most common ones like string, color, boolean, number, etc., and you can define them in the Identity Inspector

 

In the example above I am using a great UITextView subclass, SSTextView, that has two properties

1
2
@property (nonatomic, strong) NSString *placeholder;
@property (nonatomic, strong) UIColor *placeholderTextColor;

that as you can see in the screenshot, were easily defined right from within IB.

No more unnecessary IBOutlets! Yay!

FULL DISCLOSURE: Maybe this have been since version 1.0 of Interface Builder but it is really the first time I see it and I thought it was awesome!

3Jul/123

MFMailComposeViewController crash on dismissal on iOS5 and ARC

If you are like me you are already taking advantage of some of the new iOS5 methods (and ARC) like to present or dismiss a view controller.

So I used those methods to present an MFMailComposeViewController and everything was fine:

1
2
3
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
[picker setMailComposeDelegate:self];
[self presentViewController:picker animated:YES completion:NULL];

The problem appeared when I was trying to dismiss the controller after it was done sending the email, in the delegate method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
switch (result) {
        case MFMailComposeResultCancelled:
            [self dismissViewControllerAnimated:YES completion:NULL];
            break;
        case MFMailComposeResultFailed:
            [self dismissViewControllerAnimated:YES completion:NULL];
            break;
        case MFMailComposeResultSaved:
            [self dismissViewControllerAnimated:YES completion:NULL];
            break;
        case MFMailComposeResultSent:
            [self dismissViewControllerAnimated:YES completion:NULL];
            break;
        default:
            break;
    }
}

That piece of code will make your app crash with no mercy. Wait! It doesn't crash if I cancel the email MFMailComposeResultCancelled result!
Yes, that is correct. It will crash for any other result though, which makes it even more annoying.

Well, then how to fix that?
Simply use IF and ELSE IF. That is it!
Why? If you know please tell me!!!

1
2
3
4
5
if(result == MFMailComposeResultSent){
        [self dismissViewControllerAnimated:YES completion:NULL];
} else if (result == MFMailComposeResultCancelled) {
        [self dismissViewControllerAnimated:YES completion:NULL];
}
Filed under: Uncategorized 3 Comments
17Oct/110

Integer16 in Core Data Model in iOS5

The free ride is over!

Up until iOS 4.3.5 an Integer16 attribute was really misused by the Core Data Model and it was being treated as an Integer32 (I think!).

Starting in iOS5, an Integer16 attribute has its proper limit, 65535. So if you are working with numbers larger than that, you need to use a different number type.

Update your models properly and don't forget that Lightweight Migration is your best friend =)

9Aug/110

Make your own crash reporter using QuincyKit

While there are a couple of great services (HockeyApp, TestFlight) offering crash reporters for your app, these tend to be a little expensive...$20/month

But even if you are an indie developer, chances are that you have a website for your app and that your hosting plan came with a couple of SQL databases that you never use!

Well, now it's time to put those databases to good use!

 

A very good example of how this magic works can be found in the inClass app, which, if it crashes for some reason (and it never should!), it will ask the user once if he wants to always send crash reports or never send them.

 

 

The open source project we are going to use today is called QuincyKit (GitHub link). It is constantly updated and has a really good documentation and step by step process on how to setup both your iOS app and the server side of things.

And since they have a really good step by step process, I am not going to repeat it. One thing you should be aware is that if you feel a little lost, or feel like the documentation is missing something when you look at the ReadMe or the sample code, don't forget to look at the Wiki. I have found that between the ReadMe, sample code and Wiki, I was able to make it work.

Another quick note: For local symbolification, you can support multiple versions by having multiple directories with the necessary files. The required files are the .app and the .app.dSYM files for the specific version that was submitted to the App Store. An easy way to get these exact files is simply by going to Xcode and opening the organizer, look for the archive that you submitted to the App Store, and share it as an archive file. That will create an archive file that if you right click it, and select 'Show package contents', you will be able to copy the exact files that you need to symbolification. The structure of your directories and files should look something like this:

 

 

 

 

 

 

 

 

Now it's time to crush some bugs!

20Jun/110

Xcode4 and GitHub for existing projects

 

If you are unlucky, like I was, you started iOS development and didn't even know about source control.

I am sure that, like me, you manually copied the entire Xcode project's directory for every version of your app to be released. Then, you decided to be more cautious and did the same even for development versions, and even saved those copies on an online server.

No more! Now in 5 easy steps you can use the glory of Xcode 4's Git source control and  your private GitHub repository with an existing project that had no automatic source control before.

What's even more amazing is that the first 4 steps were in the Mac OSX documentation all along and I didn't even know!

So here they are:

  1. Use the 
    1
    cd

    command to switch to your project folder, making it the current working directory.

  2. Enter 
    1
    git init

    to create an empty repository.

  3. Enter 
    1
    git add .

    to copy your project files into the repository.

  4. Enter 
    1
    git commit -m "Initial commit."

    to commit all the files.

  5. Check out my previous post on How to push your Xcode4 project to GitHub and you are done!

Then, start Xcode4, open your project and take a look at your repositories and if you are lucky, like me =), you will see a brand new repository there for your project with thousands of added files.

Filed under: iOS No Comments
20Jun/114

Xcode4 and GitHub for new projects, I finally got it

After suffering ages to figure out the best way to integrate Xcode 4 and GitHub and make it as easy as possible, last weekend at the Code For Change hacktahon, I finally got it!

Here are the simple steps:

  1. Create a repository on GitHub
  2. Create a new project on Xcode4 and don't forget to check the checkbox to enable Git source control.
  3. From Xcode, commit whenever you want.
  4. Using Terminal on you Mac, go to the folder where you created your Xcode project and then type:

    git remote add origin git@github.com:yourUsername/yourRepo.git
    (of course, replace yourUsername/yourRepo with your own)
    git push -u origin master

  5. You should now see your project on GitHub. So now just continue working on Xcode and commit whenever you want. To push your new commit to GitHub simply type in the Terminal:

    git push

 

And you're done!

I will post the best way to do it with an existing project soon, so stay tuned!

Filed under: iOS 4 Comments
23May/112

Embed images into email

One of the biggest problems of the MFMailComposerViewController, provided by Apple to allow us to send emails easily, is that it hasn't been updated since it first came out leaving us with very few (yet useful) methods to create and send an email.

Since it hasn't been updated, the only way to add an attachment to the email is by calling the

– addAttachmentData:mimeType:fileName: method on MFMailComposeViewController. The problem again is that the attachment will be posted at the bottom and not inline with the rest of the email body.

 

For images, there is a simple solution =)

Since the email body only accepts an NSString with HTML code we need to encode the image data into a base 64 encoded string, then use that string and add it to your email body.

To encode the image you need to simply:

1
2
3
4
5
6
7
8
9
- (NSString *)stringBase64EncodedImage:(UIImage *)image {

NSData *imgData = UIImagePNGRepresentation(image);

NSString *dataString = [imgData base64EncodedString];

return dataString;

}

As you can see, base64EncodedString is not a method on NSData, but there is a category by Matt Gallagher that makes this possible.

After encoding the image into a string is just a matter of simply use it in the HTML code to be used for the email body:

UIImage *img = [UIImage imageNamed:@"testImage"];

NSString *dataString = [self stringBase64EncodedImage:img];

[emailBody appendFormat:@" src="data:image/png;base64,%@" alt="" width="%d" height="%d" />"", dataString, img.size.width, img.size.height];

A pretty good example can be found in inClass, when sharing a note via email as shown below.

 

 

 

 

 

 

 

 

 

 

And guess what! I made a sample XCode project too!

Filed under: iOS 2 Comments