How to Convince Someone to Be Your Technical Cofounder

Throughout the past years, I have been solicited by many friends, friends of friends, and complete strangers to be a technical cofounder/developer on a new project.

For almost all of the projects and startups that have been presented to me, I have declined.

Here are the main reasons why:

Almost always, the offer from the startup goes something like, “You create us an app for free, and we will give you X% of our company/profits in return.”

I think the founders of these startups underestimate the amount of the work it takes to build the “app” as well as valuing the X% equity.

The X value could be 100 and still developers would decline to work for free. Startups need to evaluate the way they propose working relationships by providing a clear explanation of their business and why it is worth the risk of a developer.

Here are some questions that every team needs answered and communicated to potential technical cofounders.

1) What does the current status of my startup bring to the table?

Could this developer duplicate this startup themselves? Does the ideas and execution of the business rely on specific expertise of the existing team members? In other words, what makes your current team so special and unique? I can’t stress enough how often the answers to these questions are not offered.

2) What is the problem my business is trying to answer?

This question is almost always overlooked or not communicated effectively. How do you know if this is a real problem? How much does this problem cost an average customer? Who/what says there is a problem, and why does their opinion have any credibility?

Who says that your business has a solution and does the person making the claim hold any credibily?

3) How close are you to closing business with your first customer?

If the answer to this question is more than 3 months, it will be incredibly difficult to convince a technical person to build something for free. You have to remember that decent developers have a very high opportunity cost. They could be working on any number of paying projects/jobs. Every hour they spend working on your project is costing them their hourly rate. It doesn’t mean that your idea isn’t good, it just might not be good enough to be worth the risk.

4) Why can’t I pay this developer?

You need to have a legitimate reason why you can’t pay a developer any amount for their time. Remember, it is very likely that your time is NOT equal to that of a developers. Just because you are working for free doesn’t mean that your opportunity cost is equal to someone else working for free. Could you raise money and pay the developer some discounted rate plus equity? Developers will often pay more attention to combo offers of money and equity as it lowers risk yet.

Startups should approach potential technical confounders the same way they do investors. While investors give you
dollars, developers give you
dollars in the currency of time.

iOS is the Worst Platform for Development

Releasing an application on the App Store is ridiculously inconvenient.

Reason 1: Review Time

The Apple Review period is the greatest and dumbest obstruction facing App Store development. There is no reason for it. The system of human review is inherently inconsistent and unfair. There exists some dry bullshit about “app quality” – a fundamentally flawed approach from the perspective of App discovery. Users don’t discover bad quality apps. If they do, they don’t keep them. It’s a simple system and it works. Google Play works like this.

Why does Apple really have a review board? My theory is a theory for (partly) why Steve Jobs didn’t want Flash on iOS – also a similar reason of why Apple became so loved and Microsoft so hated: Public ignorance.

Early versions of Windows involved very little security measures for executable applications in comparison to today. Who did people blame when their application crashed? Would they say, “Oh no! Sim City just froze! I wish the developers of Sim City would fix these bugs!”

No, people never used to say that. They would say, “Oh no! Sim City just froze! Windows sucks!”

My theory is that Steve Jobs looked at Flash the same way. If someone ended up visiting a buggy Flash website, they would blame the IPhone. The public a decade ago mostly didn’t distinguish between software and operating systems. Today the public is much more aware and educated about this difference. If an App is slow, people are less likely to complain about  their smartphone or mobile OS and more likely to complain to the App developer.

Only a theory, but I think it extends to the App Store review process. Steve Jobs and Apple were afraid that if there were buggy/poor apps in the App Store, people would associate bugs and poor quality with Apple – something very counter to their brand and message.

But with changing times, Apple hasn’t adapted. Guess how long it took me to get my Android app published and available on the Google Play Market? I simply upload the IPA and hit publish. I absolutely love developing for Android because it’s almost as easy as it possibly can be.

Apple’s review process is bloated with inefficiencies. The smallest changes often times involve a brand new week long review process.

Fairness? LOL. How is it fair that one person (reviewer) has complete power over your app publishing. Frustration is a nice word for the feeling one gets seeing their app rejected for a reason that was apparently ignored for another app.

According to Apple’s Responding to an App Rejection pop-up window, “Note that while other currently available apps may appear to be non-compliant, citing these will not be considered a valid reason for overturning a rejection.”

That’s swell of you Apple; looks like so many people reported these inconsistencies that you had to put a response.

Here’s the real problem with this pretentious system. Apple is saying their individual reviewer knows better than the public about which apps are “quality” and which apps aren’t.

The ironic truth of the App Store review process is that it actually creates an ecosystem of bad quality apps. Find a critical bug in your app? You can’t just replace the app – you have to go through the entire review process again! What if you have a bug that deletes all users data? What if your server that your app connects to becomes compromised? You still have to wait a week to get that update to your users! Absurd! In a week you can lose your users due to a critical bug.

How does Google approach this problem? There isn’t a problem. On Google Play you can simply replace the app with a new version from their developer console and within hours your users get the new update.

Reason 2: Application Loader

There are multiple tools out there for developers to export IPAs (Phone Gap, Unity, Adobe Air, etc). However, it is impossible to submit your App to the Apple Store unless you use the Application Loader tool that is in XCode. Have Windows? Use Linux? Looks like you’re going to have to open your wallet some more to buy a Mac computer or virtual machine to run Mac OS so you can download XCode and install this stupid Application Loader.

Here’s an obvious question… Why doesn’t Apple allow users to simply use a website upload form to upload their IPA? Is it to sell more OSX licenses?

Can you imagine if Google required users to buy a Chromebook in order to upload Apps using some “application loader” only available on Chrome OS?

Let me also point out the ineptitude of the Application Loader software itself. The Application Loader fails to checks for many issues (missing screenshots etc). For example, I recently uploaded an IPA and received a “green check mark” from the Application Loader indicating the IPA was submitted for review successfully. An hour later I happened to check my email only to see that the IPA was “automatically rejected” because it was missing a screenshot for IPhone 5 size devices… Why didn’t the Application Loader detect this issue? Even more importantly, why didn’t ITunes Connect allow me to get to a “Ready for Upload” state in the first place if I didn’t upload that screenshot?

“So what’s the big deal? Just reupload and resubmit”

Well considering that just building a “signed” IPA can take 20 minutes and submitting an IPA through the Application Loader can take 20 minutes, it is quite annoying to have to go through all of that multiple times throughout the day.

The thing I hate most in iOS development is the time wasted on bullshit. Spending an entire freaking day just trying to get my app submitted then a week to get it on the app store is ridiculous.

Developers Can’t Make Movie Apps Anymore

A few days ago I brainstormed an app idea to help users find movies they want to watch on Redbox and Netflix. A small app, nothing grandiose or too ambitious, but a simple app that would do a job.

In order for me to create these apps, I need to be able to pull (public) information from these services. Redbox inventory differs from location to location, and Netflix’s inventory changes as their movie rights expire and new titles are added.

I’m astonished at the lack of developer support from Netflix and Redbox. As of about a month ago, Netflix shut down its API service to developers.

This change means that developers can’t create an app that helps people find Netflix movies to watch. Even if you want to grab publicly digestible information like the list of movies on Netflix Instant.

Redbox has an API, but you have to apply… and wait… for them to approve of your “application” - basically you have to tell them what you’re building, your business model, etc. Considering I could probably count with one hand the number of Redbox apps out there, I am guessing that Redbox doesn’t quite see eye-to-eye with most developers’ API applications.

Hulu doesn’t even offer an official API and developers have to resort to reverse engineered libraries.  Amazon Instant does have an API, but it is stupidly wrapped under the overly complex Amazon’s Product Advertising API umbrella.

This is sad.

There is a problem in movie discovery, many people struggle to find movies they want to watch, and developers have their hands tied behind their back trying to fix this problem.

“You uploaded an APK with Invalid or Missing Signing Information for Some of Its files” Google Play, Adobe Air Error

Getting

“You uploaded an APK with invalid or missing signing information for some of its files. You need to create a valid signed APK”

while trying to publish your Adobe Air Android app to Google Play?

It’s due to a bug in Air 3.6 (and 3.7 for me). For future reference, you can find out what the error in the signing of an app are by using a tool called jarsigner. This exists in your JDK.

On windows it’s in your JDK path/bin folder. Just open up command prompt/terminal and run:

jarsigner -verify "[PATH TO YOUR APK]"

Here is the error I was getting

jarsigner: java.lang.SecurityException: SHA1 digest error for res/drawable-xhdpi
/icon.png

Here’s how I fixed it. I opened up the APK in 7zip (remember, APK is collection of files zipped together. You can actually open it up) and navigated to that res/rawable-xhdpi folder. What do you know… looks like there are TWO icon.pngs. It’s a bug in Adobe’s latest Air which packages the APK incorrectly by creating duplicated icon.png files. Probably will be fixed in later versions.

If you want to avoid upgrading your Air SDK, all you need to do is delete one of those two icon.png files from the zip file.

Command line way to do it (will delete both):
zip -d [YOUR APK.APK] res/drawable-xhdpi/icon.png

Now, if you tried uploading this APK you might get an error about the APK not being zipaligned. Due to us deleting files the APK is no longer zip aligned. Which means we have to re align the file.

Navigate to your Android Developer Tools (ADT) folder. Under the SDK’s /tools you’ll see that zipalign. You’ll need to do

zipalign -f -v -c 4 “Your APK” “Your APK 2″

Reupload the new APK (remember if you don’t put an absolute path it’ll be in the same directory as where zipalign is) and it should be accepted.

Oh the joys of Adobe Air for mobile development.

Simple Circle Packing

I am working on a new game which is was in need of an algorithm to pack characters as close together without touching. Here is a demo of my algorithm:

Get Adobe Flash player

And the code (uses TweenLite)

import flash.display.MovieClip;
import flash.geom.Point;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import com.greensock.TweenLite;

var mcs:Array = [];
var radius:Number = 5;
var c:Point = new Point(stage.stageWidth / 2,stage.stageHeight / 2);
var animationTime:Number = .5;

function addMC(e:Event= null)
{
	var mc:MovieClip = new MovieClip();
	mc.cacheAsBitmap=true;
	mc.graphics.lineStyle(1);
	mc.graphics.beginFill(Math.random()*0xFFFFFF);
	mc.graphics.drawCircle(0,0,radius);
	mc.graphics.endFill();
	mc.x = c.x;
	mc.y = c.y;
	addChild(mc);
	mcs.push(mc);
}
var t:Timer = new Timer(animationTime*1000,1500);
t.addEventListener(TimerEvent.TIMER,function(e:Event):void{
   addMC();
   arrange();
   });
addMC();
arrange();
t.start()
function arrange()
{
	var curDistanceAwayFromCenter:Number = radius * 2;
	var numMoved = 0;
	var n:Number = mcs.length;
	// Place the very first circle in the center, as the algorithm won't work for n==1
	mcs[0].x = c.x;
	mcs[0].y = c.y;
	numMoved++;
	while (numMoved < n)
	{
		/*R*SIN(180/n) = r
		SIN(180/n) = r/R;
		ARCSIN(r/R) = 180/n
		n = 180/ARCSIN(r/R)
		*/
		var numberToFit:int = Math.PI/Math.asin(radius/curDistanceAwayFromCenter);
		if (numberToFit > mcs.length-numMoved)
		{
			numberToFit = mcs.length - numMoved;
		}
		for (var j:int = 0; j < numberToFit; j++)
		{
			var cur:MovieClip = mcs[numMoved];
			// ang to center
			var ang:Number = Math.PI * 2 * j / numberToFit;
			var np:Point = new Point();
			np.x = c.x + Math.cos(ang) * curDistanceAwayFromCenter;
			np.y = c.y + Math.sin(ang) * curDistanceAwayFromCenter;
			// this if improves performance a tiny bit, would probably be way more performant if we detected if this was in the "last" circle, if not then we don't need to loop through it anymore
			if (np.x !== cur.x || np.y !== cur.y)
				TweenLite.to(cur,animationTime,{x:np.x,y:np.y})
			numMoved++;
		}
		curDistanceAwayFromCenter +=  radius * 2;

	}
}

Note that this doesn’t pack circles optimally in a space. That is a much harder problem. I was looking for a solution that would “cluster” the characters.

Annoying to Very Annoying Newsletter Practices

I really… really hate newsletters from websites I don’t want them from. What I hate even more is the unsubscribing process that websites employ. It’s like cancelling a gym membership.

Annoying Newsletter Practices

 

My flow of frustration in the unsubscribing process. Some websites employ a Hotel California approach in newsletters – you can check out any time you’d like but you can never leave.

Is it unreasonable for me to demand that I shouldn’t have to log in to a website to unsubscribe from their email list?

Custom Options Set Price to 0 in Magento 1.7 – The Fix

I’m working on a side project with Magento… There is a bug in 1.7 where when you use custom options, and your theme doesn’t include it’s own options.phtml file, the price will set to $0 (zero) when a user selects the price.

A bunch of forum posts have people talking about the problem. Basically it’s a silly bug in the javascript in options.phtml.

Basically, if your theme doesn’t have that options file in it’s theme directory, then magento looks like it defaults to the base‘s folder and includes the “default” options.phtml.

Here is the fix. I hope Magento includes it in the next Magento release!

Line 123 of options.phtml in
app/design/frontend/base/default/template/catalog/product/view/

Right now is

price += parseFloat(config[optionId][element.getValue()]);

Should be

price += parseFloat(config[optionId][element.getValue()].price);

Basically the code was trying to convert a javascript Object to a float… making the price 0.

Please share this page to others who experience the same issue.

Camera quality on iOS for Air

Having quality issues? Getting different dimensions from the camera than what you request? Read this note from Adobe:

https://bugbase.adobe.com/index.cfm?event=bug&id=2942275

cam = Camera.getCamera();
cam.setMode(320, 240, 20, false);
cam.setQuality(0, 100);
cameraVideo.attachCamera(cam);
cameraVideo.width = cam.width;
cameraVideo.height = cam.height;


//Actual Result:

cameraVideo's dimension are 320x240 when on IPhone emulator
cameraVideo's dimension are 192x144 when on IPhone

//Expected Result:
cameraVideo's dimension are 320x240 when on IPhone emulator
cameraVideo's dimension are 320x240 when on IPhone

This was Adobe’s response

When you call Setmode with some requested width and height, its not necessary that you will get the requested width and height.
The returned width and height depend on a number of factors –
1. Obviously, the values you passed in as width and height.
2. If you passed favorArea=true/false in the setmode API
3. And most importantly, the camera hardware – what are the possible resolutions (and fps) the hardware of camera on you device supports.

Since “3″ can be different for different devices you can get different values on different devices (values can vary on WIN Desktop as well with different webcams)

In this case, iOS devices again support different set of possoble resolutions –
ios Camera Presets AVCaptureSessionPresetLow AVCaptureSessionPresetMedium AVCaptureSessionPreset640x40 AVCaptureSessionPreset1280x720 AVCaptureSessionPresetHigh
3G 400×304 400×304 NA NA 400×304
3GS 192×144 480×360 640×480 NA 640×480
4 front 192×144 480×360 640×480 NA 640×480
4 back 192×144 480×360 640×480 1280×720 1280×720

The logic to compute the width and height is somewhat like this (and happens in core, same for all platforms) –

1. core asks platform to provide a list of supported resolutions. (In ios we provide the list as mentioned above , and in the spec)
2. core selects one of these resolutions, the one closest to user’s requirement (basically comparing area using percentatges but is more involved to describe in words).
3. Say user asks for 320 x 240
4. core has now to select the native supported mode closest to this. SO it can either choose 192×144 or 480×360. Seems in this case core decides to use 192×144.
5. core also changes the resolution based on the aspect ratio of the requested resolution (doing any required cropping).
6. So, you will be getting 192 x 144.

Similarly when you choose 384 x 288, core selects 480 x 360 to be the closest native resolution. Camera captures at 480 x 360 and then a cropped part of it (384 x 288) is provided to you.

Also, on Android, you get the desired values because 320 x 240 is one of the supported values by most Android cameras, thus the requested and supported better match in case of Android.
Also as I have genrally observed, Android cameras have a large number of supported resolutions compared to just 4 on iOS. Thus Android camera has a better chance to match the requested resolution. But if you ask for weird numbers like 700 x 400, you will not get that on Android too (but something else based on the above described logic)

Also the same information is mentioned in implementation spec (and comments on the spec) – https://zerowing.corp.adobe.com/display/airlinux/Mobile+Camera+Implementation+spec

See my suggestion here:

https://bugbase.adobe.com/index.cfm?event=bug&id=2953037

Might shed some light on why your video from webcam is so bad. Try increase the setMode values and get the highest quality camera quality returned. Be mindful that the resolution may be different!