Skip to content →

Category: Apple

WebPDF 1.0.0

me_icon
I needed an application that could create a PDF out of a webpage. I found a few apps on the AppStore, but none of them met my needs. I figured it would be a fun project and created WebPDF.

It’s a simple application that creates PDF’s out of webpages. The app saves the PDF, lets you view it and export it. It’s optimized for all iPhones (including the iPhone 6 and iPhone 6+) and the iPad.

I also made the source available on GitHUB: https://github.com/dougdiego/WebPDF

Comments closed

Xcode 6 Prefix Header

Prior to Xcode 6, all new projects contained a prefix header.  In Xcode 6 a prefix header is no longer included in the default project. Instead of using a prefix header you should put your imports in the files that need them.  But in the case that you need one, you can still add one.

From the menu, select File > New > File…

xcode6_prefixHeader1

 

Choose iOS > Other > PCH File

xcode6_prefixHeader2

 

In the Build Settings, each for “prefix” to narrow down your choices.  Under “Apple LLVM 6.0 – Language” find “Prefix Header”.  Add “$(SRCROOT)/PrefixHeader.pch”.  Make sure the path is correct.  When you close the dialog, it shows the expanded path.

xcode6_prefixHeader3

 

Comments closed

Xcode 6 category

After updating to Xcode 6, I thought Apple removed the ability to create a category when creating a new file. I was wrong. They just moved it.

To create a category in Xcode 6, choose File > New > File
xcode6_category1

 

Then select iOS > Source > Objective-C File

xcode6_category2

 

Choose File Type: Category.  Then enter you File name and the class you want to create a category for.

xcode6_category3

Comments closed

ld: library not found for -lPods

I’ve had this error a few times, so I figured I’d document the solution for the next time it occurred.

When doing a build in Xcode, I got the following error:

ld: library not found for -lPods

My project is setup to use cocoapods.

First make sure you are using MyProject.xcworkspace and not MyProject.xcodeproj

For me this was the case.  But I realized that I just created a new configuration for “Ad Hoc” builds.  To fix the problem I had to install the Podfile again with the command:

pod install

After running pod infall, open the project: MyProject.xcworkspace, clean your project and build.  The error should go away.

Comments closed

MHTabBarController

Source: https://github.com/dougdiego/MHTabBarController

I forked MHTabBarController, which is a custom tab bar controller for iOS 5.  I forked it to accomplish two things.

  1. I wanted to use Quartz to draw my arrow instead of using images.
  2. I wanted my arrows to go down in addition to up.

To change the direction of the arrow, just set the pageIndicatorDirection variable like:

MHTabBarController *tabBarController = [[MHTabBarController alloc] init];
tabBarController.pageIndicatorDirection = PageIndicatorDirectionDown;

You can also easily modify the colors in MHTabBarController.m here:

// TAB Colors
#define SELECTED_TAB_COLOR UIColorFromRGB(0xCF785B)
#define SELECTED_TAB_TITLE_COLOR UIColorFromRGBWithAlpha(0xFFFFFF,0.5f)
#define DESELECTED_TAB_COLOR UIColorFromRGB(0xF5EECD)
#define DESELECTED_TAB_TITLE_COLOR UIColorFromRGB(0xAF553A)

ScreenshotDownScreenshotUp

Comments closed

mbuzzy iPhone app

mbuzzy iPhone app

For the past couple of months, I’ve been working on an iPhone app for the social networking site: mbuzzy.com. It just went live into the App Store. Check it out: mbuzzy.app

One Comment

Three20: Uploading an image to a server

Here’s an example to upload an image (or any data file) to a server:

- (void) uploadMediaForUserId: (NSString*) userId {	
	NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:
								kAPIVersion, @"v",
								nil];
	// Media Name
	if( TTIsStringWithAnyText(_mediaName)){
		[parameters setObject:_mediaName forKey:@"n"]; 
	}
	
	// Media Description
	if( TTIsStringWithAnyText(_mediaDescription)){
		[parameters setObject:_mediaDescription forKey:@"d"]; 
	}
	
	// REST resource, where kMedia: @"/users/%@/media";
	NSString *resource = [NSString stringWithFormat:kMedia, userId];
	
	// Create the URL, where kServerURL is something like "http://www.dougdiego.com"
	NSString *url = [kServerURL stringByAppendingFormat:@"%@?%@", resource, [parameters gtm_httpArgumentsString]];
	// Resulting URL looks like: http://www.dougdiego.com/users/12345/media
	
	TTURLRequest* request = [TTURLRequest requestWithURL:url  delegate:self]; 
	request.httpMethod = @"POST"; 
		
	NSString * imageLocalUrl = [NSString stringWithFormat:@"documents://%@",_mediaFilename];
	NSData *imageData = UIImageJPEGRepresentation(TTIMAGE(imageLocalUrl), 0.6); 
	
	// Set the media file with the parameter: file
	[request addFile:imageData mimeType:@"image/jpeg"  fileName:@"file"]; 
	
	request.cachePolicy = TTURLRequestCachePolicyNoCache;
	request.cacheExpirationAge = TT_CACHE_EXPIRATION_AGE_NEVER;
	
	TTURLJSONResponse* response = [[TTURLJSONResponse alloc] init];
	request.response = response;
	TT_RELEASE_SAFELY(response);
	
	[request send]; 
}
Comments closed

Three20: Swipe to delete

Need to implement Swipe to delete in your Three20 project? In order to do so, I added the 3 following methods to my datasource (TTListDataSource subclass):

- (BOOL) tableView: (UITableView *)tableView canEditRowAtIndexPath:  (NSIndexPath *)indexPath {
	return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
	[tableView beginUpdates];    
	if (editingStyle == UITableViewCellEditingStyleDelete) {	
        // Make sure the row is there to delete
		if([_myModel.messages count] >= indexPath.row){
            // Get the object to delete
			MyObject* myObject = [[_myModel.messages objectAtIndex:indexPath.row] retain];

           	// Remove the object, in my case this makes an API call
            [self removeObjectById: myobject.id];
                            
            // Remove the object from the array
			[_myModel.messages removeObjectAtIndex:indexPath.row];

			// clean up
			TT_RELEASE_SAFELY(myObject);
		}
        // Delete the row from the UITableView
		[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:YES];      
	}       
	[tableView endUpdates];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	return [_myModel.messages count];
}

Note: before adding the numberOfRowsInSection method, I was getting NSInternalInconsistencyException errors.

2 Comments

Targeting the iPhone 4

Are you releasing a flashlight app for the iPhone 4 or writing an application that use the capabilities of a certain device? Apple provides a UIKit Dictionary key called UIRequiredDeviceCapabilities for this purpose.

Apple define this key as: UIRequiredDeviceCapabilities (Array or Dictionary – iOS) lets iTunes and the App Store know which device-related features an application requires in order to run. iTunes and the mobile App Store use this list to prevent customers from installing applications on a device that does not support the listed capabilities.

You set this key in the Info.plist. Here is an example which tells the App Store that your app requires a camera flash. You can use this if your app only runs on the iPhone 4:

	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>camera-flash</string>
	</array>

More: UIKit Keys

Comments closed

sgx error (background gpu access not permitted)

I recently started seeing this error in my Cocos 2d iPhone application running on iOS 4.1:

sgx error (background gpu access not permitted):
Program received signal: “SIGABRT”.

After searching around, I found this thread on the cocos2d forum.

I modified my code in the ApplicationDelegate to look like:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
	[[CCDirector sharedDirector] stopAnimation];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
	[[CCDirector sharedDirector] startAnimation];
}

- (void)applicationWillResignActive:(UIApplication *)application
{
	[[CCDirector sharedDirector] pause];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
	[[CCDirector sharedDirector] resume];
}

This solved my problem. I hope it helps someone else.

2 Comments