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.
Showing posts with label iOS. Show all posts
Showing posts with label iOS. Show all posts
Wednesday, March 21, 2012
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.
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)
{
}
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.
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.
#import <MobileCoreServices/UTCoreTypes.h>
In the application project, you also need to include the MobileCoreServices framework.
Saturday, August 20, 2011
Building OpenSceneGraph for iOS [In Progress]
After spending a few hours on trying to build OpenSceneGraph 3.0.1 on Xcode 4.2 for iOS 4.3/5.0, I finally gave up ...
The README.txt in the official OSG package describes how to generate an Xcode project using CMake. I tried to use CMake 2.8.5. Following the cmake command line described in README.txt, I got an error about not able to build a test project. Then I tried CMake GUI, but it still didn't work.
I searched the web and found a modified version at git://github.com/stmh/osg.git. This time, CMake GUI generated an Xcode project. However, when I tried to open and build this project in XCode 4.2, I got the following error:
OpenSceneGraph-2.9.10/src/OpenThreads/pthreads/PThread.c++:1: error: -mmacosx-version-min not allowed with -miphoneos-version-min
Reference: http://forum.openscenegraph.org/viewtopic.php?t=7433
It seems that CMake always made a mistake in setting the Architectures, Base SDK, Supported Platforms, and Valid Architectures consistently. Then I created a new OpenGL ES game project in XCode and followed the settings:
Architectures: Standard (armv7)
Base SDK: Latest iOS (iOS 5.0)
Supported Platforms: iphonesimulator iphoneos
Valid Architectures: armv6 armv7 armv7f armv7k
I also made sure that i386 did not appear in the CMAKE_CXX_FLAGS since I was building OSG for iOS Device.
The error disappeared, but a lot of new errors showed up:
GL
'*' was not declared in this scope
'glLoadMatrixf' was not declared in this scope
...
It seems that XCode was not able to find the OpenGL ES library. The XCode project does not contain the OpenGLES.framework. Therefore, I created a new OpenGL ES project and added the OSG project to it. I also set the Header Search Paths to point to the root of the OpenSceneGraph package.
However, I still got the following error at the end:
'vector' file not found in lwo2chunks.h
The README.txt in the official OSG package describes how to generate an Xcode project using CMake. I tried to use CMake 2.8.5. Following the cmake command line described in README.txt, I got an error about not able to build a test project. Then I tried CMake GUI, but it still didn't work.
I searched the web and found a modified version at git://github.com/stmh/osg.git. This time, CMake GUI generated an Xcode project. However, when I tried to open and build this project in XCode 4.2, I got the following error:
OpenSceneGraph-2.9.10/src/OpenThreads/pthreads/PThread.c++:1: error: -mmacosx-version-min not allowed with -miphoneos-version-min
Reference: http://forum.openscenegraph.org/viewtopic.php?t=7433
It seems that CMake always made a mistake in setting the Architectures, Base SDK, Supported Platforms, and Valid Architectures consistently. Then I created a new OpenGL ES game project in XCode and followed the settings:
Architectures: Standard (armv7)
Base SDK: Latest iOS (iOS 5.0)
Supported Platforms: iphonesimulator iphoneos
Valid Architectures: armv6 armv7 armv7f armv7k
I also made sure that i386 did not appear in the CMAKE_CXX_FLAGS since I was building OSG for iOS Device.
The error disappeared, but a lot of new errors showed up:
GL
'*' was not declared in this scope
'glLoadMatrixf' was not declared in this scope
...
It seems that XCode was not able to find the OpenGL ES library. The XCode project does not contain the OpenGLES.framework. Therefore, I created a new OpenGL ES project and added the OSG project to it. I also set the Header Search Paths to point to the root of the OpenSceneGraph package.
However, I still got the following error at the end:
'vector' file not found in lwo2chunks.h
It seems XCode cannot locate the standard library. I have no clue how that can happen.
============
I just found a post about how to minimize the size of the osg library for iphone:
http://forum.openscenegraph.org/viewtopic.php?t=7224
Summary:
we should build the library in arm 7 only for the device, since arm 7 is for 3GS and above. I think there is no point to build the library in arm 6 now, since iPhone 3G or earlier are relatively old now.
We also only need OpenThreads, osg, osgDB, osgGA, osgUtil and osgViewer. We can probably throw away all of the plugins.
We should also build the osg libs with Optimization set to Fastest-Smallest.
BTW, the same post also mentions that display lists are not available in OpenGL ES. Therefore, we should turn off OSG_GL_DISPLAYLISTS_AVAILABLE.
==========
I found another post that mentions Apple loosened the terms on their license agreement to allow for dynamic linking and plug-ins now:
http://forum.openscenegraph.org/viewtopic.php?t=6582
BTW, Thomas Hogarth is a person who successfully built OSG for iOS and also published an iOS game called Alient Attack.
============
I just found a post about how to minimize the size of the osg library for iphone:
http://forum.openscenegraph.org/viewtopic.php?t=7224
Summary:
we should build the library in arm 7 only for the device, since arm 7 is for 3GS and above. I think there is no point to build the library in arm 6 now, since iPhone 3G or earlier are relatively old now.
We also only need OpenThreads, osg, osgDB, osgGA, osgUtil and osgViewer. We can probably throw away all of the plugins.
We should also build the osg libs with Optimization set to Fastest-Smallest.
BTW, the same post also mentions that display lists are not available in OpenGL ES. Therefore, we should turn off OSG_GL_DISPLAYLISTS_AVAILABLE.
==========
I found another post that mentions Apple loosened the terms on their license agreement to allow for dynamic linking and plug-ins now:
http://forum.openscenegraph.org/viewtopic.php?t=6582
BTW, Thomas Hogarth is a person who successfully built OSG for iOS and also published an iOS game called Alient Attack.
Saturday, March 5, 2011
Don't retain UIColor, and don't release it
UIColor manages the lifetime of colors it returns. The caller is not supposed to retain it and release it.
Objective-C's protocol's property cannot be inherited
None of the Apple's Objective-C documents or programming guides that I have seen show an example of declaring a property in a protocol and the protocol is inherited. I declared a property in a protocol by Xcode fails to recognize the property.
Thursday, February 17, 2011
[NSArray objectEnumerator]
NSEnumerator * enumerator = [array objectEnumerator];
id arrayItem;
while (arrayItem = [enumerator nextObject]) {
// Do something about arrayItem
}
id arrayItem;
while (arrayItem = [enumerator nextObject]) {
// Do something about arrayItem
}
Subscribe to:
Posts (Atom)