Wednesday, March 21, 2012

iOS: Building an app for Ad-Hoc Distribution

1. Create a Distribution Ad-Hoc Provisioning Profile in the iOS Provisioning Portal. Download the profile and install it onto the computer that builds the app.
2. In the project Build Settings, change the Code Signing Identity to the Ad-Hoc profile.
3. In the Product menu, click Build For -> Archiving.
4. In the Product menu, click Archive.
6. In the Window menu, open the Organizer.
7. In the Organizer, click the Archives tab. You should be able to find the new archive.
8. Click Distribute...
9. Choose "Save for Enterprise or Ad-Hoc Deployment" and click Next.
10. Choose the same Ad-Hoc profile.
11. Choose a name and folder for your app binary. It will be saved in the .ipa format.

To test your app binary, you can give the profile (.mobileprovision) and the app binary (.ipa) to your beta tester. Make sure that when you create the profile, their device IDs are also included in the profile. Then, they will need to drag the profile and the app binary into iTunes->Apps page. When the testers syncs the iOS device, the app should appear on the device.

Saturday, March 10, 2012

The Maximum Number of Rows in UITableViewController

I am quite interested in find the number of rows that UITableViewController supports. The result is between 40,000,000 and 50,000,000:


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return 40000000;
}

A table view with 40,000,000 rows works fine but with 50,000,000 rows it does not.

Saturday, February 25, 2012

iOS: Run-time error when using a class category in a different static library

When you are calling a member function defined in a class category (https://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html) from a different static library, you might see a run-time exception of "selector not recognized".

This is a well-know issue with Xcode and iOS. There is a technical note from Apple to describe the problem and the workaround by using the -all_load flag or the -force_load flag followed by the archive path:

https://developer.apple.com/library/mac/#qa/qa1490/_index.html

There is also another workaround without defining the flag. In the file that define the class category, add a C function to the .h and .m, and call this function anywhere in the project that you call the member function of the class category. For example, if you have a class category called UIImage (A) in UIImage+A.h and UIImage+A.m, you can add a function like this:


UIImage+A.h
------------------
// This function needs to be called in the file that uses UIImage (A)
void forceLoadUIImageCategoryA(void);

@interface UIImage (A)
...
@end


UIImage+A.m
------------------
void forceLoadUIImageCategoryA(void)
{
    // Do nothing
}

@implementation UIImage (A)
...
@end


In the file that uses any member functions of UIImage (A), call forceLoadUIImageCategoryA(); anywhere. Calling this C function will make Xcode link the .h and .m.

Xcode warning: no previous prototype for function ...

This warning appears when you define a C-style function like this:

In .h:
void foo();

In .m:
void foo()
{
}

However, according to C standard, you should define the function with the void keyword if there is no parameters in your function:

In .h:
void foo(void);

In .m:
void foo(void)
{
}

Sunday, February 12, 2012

Why UIView's autoresizingMask does not work

I was trying to use to autoresizingMask in a UILabel to resize the width when the device is rotated. Following my first instinct, I wrote label.autoresizingMask = UIViewAutoresizingFlexibleWidth. However, the label didn't resize. Why?

There are a few values for the mask such as UIViewAutoresizingNone, UIViewAutoresizingFlexibleRightMargin, UIViewAutoresizingFlexibleLeftMargin, and UIViewAutoresizingFlexibleHeight. I tried to use UIViewAutoresizingFlexibleRightMargin or UIViewAutoresizingFlexibleLeftMargin but there was no difference.

Wait a minute. If we need to set those values to enable flexible margins, width, and height, what does it mean if we leave them unset? If I only set the autoresizingMask property to UIViewAutoresizingFlexibleWidth, it actually means Flexible Width AND Fixed Left Margin AND Fixed Right Margin. Even though the width is flexible, the fixed left and right margins do not allow the flexible width to expand or shrink.

Now, it is clear that when we need to set flexible width or height, we must also set  at least a corresponding margin to be flexible at the same time. For example, if we want the label to expand the end of the text (assuming that the text goes from left to right) when the width changes, we should set autoresizingMask to UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin so that the label can expand it's width at the right margin.

Sunday, February 5, 2012

Use of undeclared identifier 'kUTTypeImage'

This constant is declared in UTCoreTypes.h in the MobileCoreServices framework. In the .m files that you use the constant kUTTypeImage, import the above .h file:

   #import <MobileCoreServices/UTCoreTypes.h>

In the application project, you also need to include the MobileCoreServices framework.

Thursday, January 12, 2012

Rendering images in a background thread in Qt

QImage instead of QPainter should be used. According to the QImage class reference, QPainter can be used to draw directly onto images. When using QPainter on a QImage, the painting can be performed in another thread than the current GUI thread.