Open the main plist file (project_name-info.plist).
Add a new row with key “URL types” (“CFBundleURLTypes”).
Under “Item 0”, Add a new row “URL identifier” (“CFBundleURLName”) and add a unique identifier to it (e.g. domain+appname like the row “Bundle identifier” (“CFBundleIdentifier”) “com.domain.${PRODUCT_NAME:rfc1034identifier}”).
Still under “Item 0”, add a new row “URL Schemes” (“CFBundleURLSchemes”).
Under this rows’s own “Item 0”, add the URL scheme prefix (e.g “appname”)
Create a new project, select “Cocoa Touch Static Library”.
Add your library code there, ensure it builds.
Pick your public relevant .h files, right click on them and select “Set Role” -> “Public”.
On Finder, after a build, check if there are folders like “build/{Debug}-{iphone{os,simulator}}/usr/local/include/*.h” with the .h files just set to public, as well as the library (lib*.a) at “”build/{Debug}-{iphone{os,simulator}}/”.
On the real project, create a folder group called “Dependencies” (optional, just for organization purposes).
From the Finder, drag the library xcode project (the blue .xcodeproj icon) into the real project XCode’s Dependencies folder. Ensure “Copy items…” is unchecked.
On the XCode sidebar, open the “Targets”, “project name” so you can see the “Link Binary with Libraries” icon.
On the XCode sidebar, open the library project and drag the “lib*.a” into the just opened “Link Binary with Libraries” icon.
On the XCode sidebar, open “Targets”, “project name”, run “Get Info” (Command-i).
On the “Target “project name” Info” window, pick “General” tab, “Direct Dependencies” “+” icon, click on the library project icon.
Still on the “Target “project name” Info” window, pick “Build”. On the “Search in build settings”, enter “header search”.
On the “Header Search Path” item, add a new entry with the relative path of the library in the format (including the quotes, just in case any folder has spaces or special chars) “${PROJECT_DIR}/../{LibrariesFolder}/{LibraryFolder}/build/${BUILD_STYLE}-${PLATFORM_NAME}/usr/local/include” (notice no “/” at the end)
Alternatively (specially if for some reason the “usr/local/include” is non existent, one can also set a folder like “${PROJECT_DIR}/../{LibrariesFolder}/{LibraryFolder}” (notice again the lack of “/” at the end, and the quotes around), and tick the “Recursive” checkbox.
// run this once mach_timebase_info_data_t timer; mach_timebase_info(&timer);
// this returns the current time in nanos, but not in a perfectly human readable format - e.g. don't expect it to be number-of-nanos-since-1970 or something, like the unixtime. uint64_t start_time = mach_absolute_time();
// do something that takes time
// now calc the elapsed time uint64_t now = mach_absolute_time(); int64_t elapsed = now - start_time; elapsed *= timer.numer; elapsed /= timer.denom; printf("Elapsed time: %lld ns\n", elapsed);
Here’s two of the ways to show an CGImage into the screen.
The first is to use the proper UIImageView and UIImage objects:
CGImage cgImage = ...; // the CGImage to show UIImageView *imageView = ...; // the UIView to show into imageView.image = [UIImage imageWithCGImage:cgImage];
The second one, faster it seems, is to load the image directly into the frame buffer:
CGImage cgImage = ...; // the CGImage to show CALayer *layer = ...; // the CALayer to show into layer.incoming = (id)cgImage;
To get a layer to show the image, just create a new CALayer, or reuse the layer from a UIView, using the UIView as a simple way to position the image at the right place.
For the simplest version, add the following to your UIViewController:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSSet* allTouches = [event allTouches]; switch ([allTouches count]) { case 1: { // one finger UITouch* touch = [[allTouches allObjects] objectAtIndex:0]; switch ([touch tapCount]) { case 1: { // single tap // do something break; } case 2: { // double tap // do something break; } } break; } } }
Now that we know how to deal with single an double taps, I’ll have to ask you to completely forget about this code. One of the things that saddens me the most are the apps that expect a single finger to be pressed, neglecting the whole multi-touch capability of the iOS devices. This gets more visible when the apps are used by kids - they will always either use more than one finger to try something (sometimes even the whole hand), or will put a finger on one corner of the screen while holding the iThing, and try to press something else on the other corner with the fingers of the other hand. Stop thinking from a PC perspective! Always expect multiple touches and process each touch and each finger as if a single finger would have been used.
Note: In case we’d want to support only a single landscape mode (either “right” or “left”, it would be possible to skip the UIViewController and have the window move the status via the UIApplication and have the view be rotated manually, but in this example we want to support both landscape modes so we can e.g. rotate the iThingy and still see the stuff at the right orientation.
Now we need a UIViewController with the following code:
And one possible trick to ensure the view size is correct after the rotation (in this case because of the space used by the status bar), load the stuff after the view is rotated with something like this:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { // does not work on the iPhone simulator if(fromInterfaceOrientation == UIInterfaceOrientationPortrait)
if(!shown) { shown = YES; // add "BOOL shown;" to the interface [self show]; } }