markjnet

iPhone Conference 360 iDev San Jose April 2010

n115911253310_1478Are you going to 360 iDev San Jose 2010 in April? Its by far the best iPhone developers conference I know of… and I’m speaking at it this year. I’ll be introducing people to customer development and telling the story of our app Friend Focus for Facebook.

This year there’s 40 sessions, 3 panels, almost 40 speakers, 5 different Hands-On training sessions, all included for the price of $599 which IMHO is crazy good value. I attended in 2009 and it blew my mind. Here’s some of what I got out of the 2009 conference:

  • Learned lots of inside knowledge about Apple that you can only learn from experience with them, including guidance on the mysteries of the approval process that easily saved me several thousand dollars in wasted development time on my own apps and helped strengthen my consulting practice.
  • Got the inside scoop on mobile advertising, what works, what doesn’t.
  • Met and made friends with a bunch of expert developers and iPhone business entrepreneurs including several chart topping studios and major iPhone app review sites – extending my network of experts to ask for help, advice, and press contacts.
  • Introduced to several companies I’m now doing business with.
  • Shared sales numbers with other developers and got a bunch of marketing tips.
  • Got helpful advice on negotiating a licensing deal I was putting together for one of my apps.
  • Learned techniques for memory optimization; SQLite; advanced debugging using notifications; core animation;
  • Had a ton of fun!

12660_181780978310_115911253310_2937860_2878172_nThe intimate size of the conference is very conducive to making friends and sharing insider knowledge that’s really hard to find elsewhere. Indie developers will be there in numbers, both successful and struggling, and there will be a good mix of major studios and iPhone companies represented too. You’ll be able to both vent your frustrations with peers and grill an Admob Google executive about eCPMs. Really, its tremendous value and great fun. Go and register now.

12660_181782603310_115911253310_2937942_7897015_n

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Tweeting from an Ad on the iPhone Using URL Schemes

Lately I’ve been experimenting with promoting out app ‘Friend Focus (for Facebook)‘ by ‘turning out the vote’ – ie getting our existing users to help us promote Focus. Once I’ve found a formula that works well we’ll implement the scheme in app and figure out a way to reward users for helping us, but for now I’ve been using house ads. House ads are our own ads placed in our app using the ad network we’re integrated with. Admob in this case. This is a great way to try out ad copy and experiment with different promotions because its all done with no code updates to our app, all I have to make is a simple HTML landing page for each ad.

A recent campaign we’ve been running is ‘Tweet your support for Focus’, which asks people to tweet saying that Focus is great:

Tweet support for Focus ad

Tweet support landing page

Naturally the tweet has to be pre-filled, which lets me use a bit.ly link so I can track the effectiveness of the campaign. A ‘tweet me’ link is pretty easy on the web, but this is on people’s iphone. Twitter users with lots of followers (ie the people we want to tweet) aren’t using the twitter website on their iPhone, they’re using a twitter app, of which there are many to choose from! So how do we turn a click on my ad into a pre-filled tweet right inside someone’s pre-logged in twitter app of choice? The solution is to use custom URL schemes. Several iPhone twitter apps have custom url schemes that allow you to launch them and pre-fill a tweet using their custom url. This works just as well from the landing page of an admob, in code in a native app, in a web page in mobile safari, or a link in an email.

Hmmm, but which twitter app to choose? Turns out you can choose them all! I wrote some simple javascript to just open all of them – one of them is bound to hit. The code is below. I picked 5 of the most popular twitter clients and included them. The script works great in the UIWebView that Admob opens to show the landing page for the ad, because the UIWebView isn’t throwing up a dialog saying “couldn’t open that URL” for urls where a scheme isn’t installed on the devide. Its imperfect as a web page because of these alerts, which you will see if you try it. I tried a bunch of things – using the tweet url for an image src, in an iframe, as a form submit. I also played with timers and onblur event to try to cancel out the urls tries upon returning to the page in Safari. If someone could figure out the perfect javascript for this that works in Safari and post here in the comments, that would be very awesome.

Go ahead and try it by clicking the ad above, and if you tweet your support for Focus, that would be splendid! As you can see to the left, it works… we’ve had 28 tweets so far, from a variety of twitter apps, which has generated 165 click throughs to the Focus website. Thanks to everyone who tweeted for us so far. Below is my hastily put together javascript.

 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Tweet Focus Support</title>
 <meta name="viewport" content="width=300; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0" />
 
<script type="text/javascript">
var msg = "Get%20the%20best%20Facebook%20on%20%23iphone%20with%20Focus%20for%20Facebook%20http%3A%2F%2Fbit.ly%2FFocus4Facebook%20%40focusedapps%0A";
var tweetTry=0;
var tweetTryCancel=false;
var tweetTrys = new Array();
tweetTrys[0]="tweetie:///post?message="+msg;
tweetTrys[1]="twitterrific:///post?message="+msg;
tweetTrys[2]="echofon:///message?"+msg;
tweetTrys[3]="twit:///post?message="+msg;   //twitelator
tweetTrys[4]="x-birdfeed://post?text="+msg;
 
function tweetPress() {
	tweetTryTime=0;
	tweetTry=0;
	tweetTryCancel=false;
	tweet();
}
 
function tweet() {
//alert("tweet");
	if (tweetTryCancel) {
		alert("cancel");
		return;
	}
	var currentTime = (new Date()).getTime();
	if (tweetTryTime!=0) {
		var elapsedSinceLastTry = currentTime-tweetTryTime;
		//alert(elapsedSinceLastTry);
		if (elapsedSinceLastTry>400) {
		alert(elapsedSinceLastTry);
			tweetTryTime=0;
			tweetTry=0;
			tweetTryCancel=false;
			//alert("reset");
			return;
		}
	}
 
	tweetTryTime = currentTime;
 
	var url = tweetTrys[tweetTry++];
	if (tweetTry>5 || url==null) return;
	if (tweetTryCancel) return;
	//alert(url);
	if ("http:"==url.substr(0,5)) {
		window.location=url;
		window.setTimeout("tweet()",10);
		return;
	} else {
		//window.location=url;
		var obj = document.getElementById("if1");
		obj.src = url;
		window.setTimeout("tweet()",10);
		return;
	}
}
 
function onBlur() {
	tweetTryCancel = true;
};
 
 
window.onblur = onBlur;
 
</script>
</head>
<body>
<div style="margin-right: auto;margin-left: auto;width: 280px;background-color: #DFEFF5;padding: 5px;border: 3px solid #6080C0;"><center>
  <div align="center" class="style1">Tweet Your Support  </div>
  <p align="left">We need your help to spread the word about Focus for Facebook. If you use Twitter, please take a moment to...</p>
 
  <p align="center"><a href="" onclick="tweetPress(); return false;" }><img src="tweetSupportApp.png" alt="tweet support" width="245" height="41" /></a></p>
 
  <p align="center"><a href="http://clicktotweet.com/ha89H"><img src="tweetSupportWeb.png" alt="tweet support" width="245" height="41" /></a></p>
 
  <table width="219" height="94" border="0" align="center" cellpadding="2">
    <tr>
      <td height="15" colspan="3">&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="2" align="left" valign="top"><img src="logo62.png" width="62" height="62" /></td>
      <td rowspan="2" align="left" valign="top">&nbsp;</td>
      <td height="5" align="left" valign="bottom">Thanks,</td>
    </tr>
    <tr>
      <td height="5" align="left" valign="top"><p>Mark &amp; Rob, Focused Apps.</p>
      </td>
    </tr>
  </table>
  <img src="" width="1" height="1" id="img1" /><img src="" width="1" height="1" id="t2" />
  <form id="form1" name="form1" method="get" action=""></form>
  <iframe id=if1 src ="" width="1" height="1"></iframe>
 
  </div>
</body>

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

iPhone Memory Debugging with NSZombie and Instruments

When your iPhone app crashes with ‘BAD ACCESS’ you’re in trouble – a memory bug where you tried to call a method on a object that was already deleted. Instruments has support for NSZombie – a feature that makes it easy to find the source of the bug by showing you a full history of every alloc, retain, release, and autorelease of the object that caused the crash! Wow. Here’s how:

Basic steps are:

  1. Run in Performance tool ‘Object Allocations’
  2. Stop running and set options on ObjAllocations instrument: ‘Enable NSZombie’ Detection and ‘Record Reference Counts’
  3. Re-run from instruments, when it crashes, click the arrow in the popup zombie dialog
  4. Open up the stack trace view and see the full memory history of the problem object
  5. Wow, how awesome is that?
  6. If you love this post, do me a favor and check out our Free app Focus for Facebook
  7. You might also like my memory management tutorial and other posts under ‘App Development’.

Enable Zombies in Instruments

Enable Zombies in Instruments

Here’s a link to the demo program: ZombieDebug Demo Project. The code we’re looking at in the video is:

@implementation ZombieDebugViewController
 
@synthesize objArray;
 
-(void)rewriteText {
NSMutableString* s = [NSMutableString stringWithCapacity:100];
for (id obj in objArray) {
[s appendFormat:@"%@,\n",obj];
[obj release];
}
label.text = s;
}
 
- (void)viewDidLoad {
[super viewDidLoad];
self.objArray = [NSMutableArray arrayWithCapacity:10];
[objArray addObject:@"I'm a string object"];
[self rewriteText];
}
 
-(IBAction) tapButton:(id)button {
NSNumber* n = [NSNumber numberWithLong:random()];
[objArray addObject:n];
[self rewriteText];
}
 
-(void)dealloc {
[super dealloc];
self.objArray=nil;
}
 
@end

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Focus for Facebook iPhone App

Announcing our new free iPhone app: Focus for Facebook.  Focus presents Facebook® in a streamlined view on your iPhone so you can quickly scan through and stay up-to-date on the go. Focus has some neat features we designed to make it the best mobile Facebook experience we could:

Streamlined Facebook: See new posts, comments, notifications, photos and links in a single, compact, easy-to-scan list. Also you can comment, like, update your status and post photos on the go.

Don’t re-read the same stuff: Focus remembers what you’ve read, and highlights new posts and comments, so you never miss new content.

No more app spam: Focus automatically keeps those games and quizzes out of your feed.

We’ll be updating Focus as soon as we can with Facebook chat, inbox / messages, and full photo browsing. Get Focus for Facebook FREE in the app store now.

feed2 detail2

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Debugging Tip – objc_exception_throw breakpoint

If an exception is thrown when debugging an iPhone app, without your own exception handling code, that exception won’t stop the debugger until the call stack has totally unwound. On that journey through the call stack it gets caught and disguarded in the event loop. That’s a bummer because then the debugger can’t show you where original exception was raised. This problem is easy to fix by adding a symbolic breakpoint for the runtime’s objc_exception_throw function, which is called as soon as the exception occurs. Here’s how:

1) Run the app in the debugger. There’s an exception we can see in the debugger console:

screen 2

2) Open the debugger from XCode menu Run->Debugger. The stack we can see where the debugger paused is the useless stack where the event loop code caught the exception and then bombed out with its own exception.

screen 4

3) From XCode menu Run->Manage Breakpoints -> Add symbolic breakpoint we add ‘objc_exception_throw’

screen 12

4) Now when we debug run again, the debugger stops as soon as the oringinal exception was thrown, we can see exactly where, and we can poke around an inspect variables etc.

screen 11

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Next Page »

  • Categories

  • markjnet