Tuesday, July 27, 2010

libAdMob.a missing from iPhone project

Did you check out someone's iPhone project (or sample code) from SVN and get a "library not found, -lAdMob" error?

That's because some SVN clients are set up to ignore .a files, which is how the AdMob library is distributed. What you'll need to do is to contact the person who checked in the project and get them to add the .a file (it's about 2MB) to the SVN repository. Or, you can download it yourself.

To download libAdMob.a, go to admob.com, sign up, create a new App for them, and THEN it will let you download the SDK code. No, you can't just download the SDK, the AdMob developers are a bunch of stupid cunts that don't want to let you have an easy day; they'd rather force you to sign up and create an app you'll never actually ship, instead. They *want* the clutter. They *want* to hassle you, one of their developers. That's because (and I hate to repeat myself) they are a bunch of stupid cunts.

Saturday, July 24, 2010

Sharing to Facebook from an iPhone App

First, let me say that the sample code provided by Facebook and others is teh suck. Some of the top hits when you search for stuff are broken samples. Be careful out there!

Second, the documentation itself is crap.

So I'm here to go over the flow that I used to share to facebook. If you're developing an iPhone app and want a "Share on facebook!" sort of thing, then start by perusing the readme: http://wiki.developers.facebook.com/index.php/Facebook_iPhone_SDK That's nice and all, but it's not shippable.

Background #1: Facebook updates. The 'stories' that appear on your wall, and are shared to your friends' home pages, are all little text doodads with links to content stored elsewhere. Adding a story to a user's wall is the simplest thing, and it's what most of those Facebook games do. There are status updates and then there are other stories; a status update is what happens when you don't include an actionable item (a 'call to action' type link). Mostly you just pull some key/value pairs together (see Facebook's list of attachments) then make a request.

Background #2: You can't upload images to a wall, only to your photo album, for example. Developers making utilities, games, and entertainment want to add a story that contains a custom image. You might note that most facebook games don't do that; they use a generic image instead, like a picture of a cow or sheep or barn as FarmVille does. Uploading a custom image is tricky. If you want a wall story with a custom picture, you have to either (a) first upload the image to the user's photo album (the default one has a limit of 500 photos, one dedicated to your app will have a 1000-photo limit), which means that two stories will appear back-to-back on the user's wall, or (b) store the image somewhere else instead and link to that.

What you wanna do:
0) First, allow the Facebook Developer application. Go to http://www.facebook.com/developers and 'Allow' it.
1) Create an application (see the image on the right). Yes, you might need to make your application page pretty.
2) Go to XCode. Create your own facebook helper class. I called mine FacebookHelper, cuz I'm creative like that. The point of creating this class is to not mix facebook delegates and dialog handlers and all that crap into your other classes. Posting isn't just one function call (there can be three or more callbacks involved), so partitioning it all into a separate class will help.
3) Add an entry point to this class. I haven't yet refactored this out; right now, I copy-n-paste the class into a new project and edit the implementation. So my entry point isn't
- (void) Share:(NSString*)shareText;
blah blah blah, but just
- (void) Share;
4) That entry point will look roughly like this:
{
if (self.session==nil || !self.session.isConnected)
 [self ShowLogin];
else if (!havePermission)
 [self AskPermission];
else
 [self PostToWall];
}
5) Write the FB login code and delegates. This means creating an FBLoginDialog and show'ing it.
6) If you need extended permissions of any type, create & show an FBPermissionDialog. Note that your FBDialog delegate callbacks will need to differentiate the type of dialog shown. I did this by sticking an enum in the dialog's "tag" field, and switching on it in the dialog:didFailWithError, dialogDidSucceed:, and dialogDidCancel: callbacks.
7) Finally, post to the wall. Do this by creating an FBStreamDialog, add an attachment string with all your parameters, like so:
 "name":"My App Name","message":"User enters this text, this is placeholder","caption":"etc"
These key-value pairs will include a link to your app and a link to the image to use in the post.
7b) If you're uploading an image to one of the user's albums, you use an FBRequest instead of showing an FBStreamDialog.
{
 NSMutableDictionary* args = [[[NSMutableDictionary alloc]init]autorelease];
 [args setObject:@"my caption" forKey:@"caption"];
 FBRequest* request = [FBRequest requestWithDelegate:self];
 [request call:@"photos.upload" params:args dataParam:image];
}

Later on I'll upload the entirety of the class so that you can see it all in process. Plus I'll probably clean this post up, too... meanwhile, I've got to run.

Saturday, July 10, 2010

some notes on learning

The best teacher will show you theory, give you both good & bad examples, explain why the bad examples don't work, then watch you try it and give you feedback. The lower the time lapse between trying something and getting feedback, the faster you'll learn.

If you don't have the spare $50k laying about to hire a personal instructor for your desired task, you're stuck searching and finding this stuff on your own.

Programmers

What if you're a programmer? The best place to go for theory is textbooks. Usually they're thick with theory but light on practice, and some of their theory will only work in the toy examples that academics are used to. But that's fine; you're here for the theory.

Good & bad examples are somewhat easy to google for. "Best practices" and "horror stories" are good keywords. Look for people that suggest bad experiences and ask them to expand on it.

Newbs tend to have bad habits, but finding out what those are and why they're bad is difficult. Books and didactic websites are again your best bets here.

The hard part is feedback. For that you need a coding buddy; someone (and I would suggest someone you don't work with) to serve as a sounding board, and will develop their own library of best practices, bad habits, and good feedback. You can give yourself feedback by (as I mentioned early) refactoring your own code shortly after you write it. Go back and rewrite the last app/utility/website you built! Might seem like "a waste," but it's amazing what you'll learn in the process.

Gamers

Game theory is woefully light. Good luck with that.

Good examples are easy to find; there's tons of videos of good players and really bad players. The hard part is figuring out why the good players succeed. Sorry. Good luck with that.

The easiest way to get better, actually, is to study mistakes. Look at people that get crushed and try to figure out what they did wrong. Fraps your own play and study it. A lot of people just hate doing that. Suck it up, cowboy. You'll learn fastest that way.

Three Steps to Being a Better Programmer

How to Be an Awesome Programmer in three easy steps:
1) Practice
2) Study the experts
3) Learn from your mistakes

Practice is by far the easiest thing to do. As I've mentioned before, I think the great lesson of Gladwell's Outliers: The Story of Success is that one gets better at something by practicing. In anything competitive, by practicing against better players (that's #2). But time on the field isn't enough; you actually have to learn something.

I've been thinking about playing Warcraft again, and in preparation I've watched a few Arena videos to get me motivated. That lead to watching some Quake videos, and that reminded me of my old days playing Quake. Obviously, the top players (at any online game) have played a lot. But time on the battlefield isn't enough; being smart by itself isn't enough.

I also read a number of "how to get better at Arena/Quake/Whatever" articles, and that led me back to Gladwell, a bunch of other articles and books, and eventually to the pickup community. A lot of people go to coaches for learning. This mostly gives the student a chance to find out who the masters are, so that he can study what they do. It's difficult to get better when you're around people that are as good as you; you're forced to learn everything yourself. Coaches will tell you what to practice, and they'll show you better players, too.

But learning that way is still pretty much learning by yourself. You just have better examples to teach you.

The better way to learn is to have a teacher. The teacher will look at your performance and suggest what to do different. They'll point out your mistakes.

That's the hardest part of getting better

Most people don't like to go back and revisit old work, but it's potentially the most instructive. And watching the pros at work isn't enough; a good teacher will point out what they're doing.

The the pickup community, "instructors" either "teach by example" (which is really doing what they do and then hoping that you figure it out on your own) or stick to mechanical skills (like body language).

In online games, there are no coaches; everyone learns by themselves. In this sort of community, the best thing to do is to play with the best.

In programming, the cost of practice is extreme; there's a plethora of experts; and they all say different things. About the easiest way to improve your programming is to refactor.

The best way to be a better programmer

The easiest way to improve is to try different tools, languages, and platforms. Until you try a decent interface builder, you'll probably think the one you're using is good enough. Until you try a functional language, you'll think your OO skills are all you need. Until you use a modern compiler, you might think the crap you have to do to satisfy your current compiler are acceptable.

Theory is nice. Where's the practice?

One of the things I learned while working on my other blog is just saying "try a new platform" is vague. Are there any that I could name that would be good?

Why, yes. Yes there are.

1) F#. Try building little Windows utility apps using it. Dive into the community to find better ways of doing it. Read a book or two and pick up the common wisdom.
2) iPhone dev. This is a great place to learn from other's mistakes, because the platform and tools are such utter shite. Seriously. The rest of the world is using modern compilers and tools that work. (OK, honestly, this entry is a bit of a joke, but you will learn message-passing.)
3) Find an open-source project using Perl or Python. Diving into one of these languages is the best way to learn them.
4) Website dev using C# and ASP.NET. Modern compilers & tools are an amazing thing.

I'm sure there's better examples out there; use these suggestions as a start.

Wednesday, July 7, 2010

Four Things Good Programmers Do

After a five-month ski vacation I'm back in civilization job-hunting. The interview process is interesting from the interviewee side, to see what many companies think that they want. To me, a good programmer isn't someone that's spent seven years with Technology X; in that much time one learns a lot of tricks, but good programmers don't just know tricks - they're supposed to be writing code.


#1 Ship

Good programmers finish what they're working on. I think being left in a cubicle by yourself makes it easy to succumb to creeping featuritis. To get caught up in 'perfecting' a system which might have a minor role in the finished product. Good programmers ship. They get things in shape to release, and they release. The more things you release, the more you learn about what customers want. And you also learn how to release better software faster.

To me the lesson of Outliers is that everyone learns by doing. The more you do something, the better you get at it. The people that are really good at stuff - from major-league sports players, to Bill Gates, to writers and artists - are good because they have had a lot of practice.

Spinning your wheels polishing bad code is practice polishing, not practice shipping. If you want to hire a good coder, you want someone that's had practice turning a working prototype into a professional, shippable product.

#2 Working

It a similar vein, good programmers write working code. I've worked with too many coders that write buggy code that barely works - or doesn't work at all. You'd think they wouldn't still have jobs programming, but the interview process is pretty damn flawed. It's like a first date. The interview I had today was mostly feel-good; a guy on the team liked talking about Agile and I could talk the talk. Walking wasn't really part of the discussion.

I'm surprised when I see someone check stuff in that doesn't actually work. It suggests that the programmer has bad habits and doesn't test what they write. To them, programming is something you do in the editor. As soon as their code compiles, they check it in and move on. Yes, I've actually worked with coders like that. They think they're gods; they think they don't make mistakes.

The good programmers on your team, the ones you want to keep and promote, are those that actually get stuff working. When a web page is supposed to do something, when a class is supposed to commit a transaction or pull data, it should do so. Some guys get 90% of the way there, and other coders step in and turn a code checkin into a working feature.

Mr. 90% won't be able to ship software. He might write a lot of code, but the stuff he checks in doesn't actually work. Ask your coders; they'll be able to tell you who on the team is Mr 90%. Fire Mr 90%.

#3 Robust

There's a lot of work that goes into the "foundation" of a feature. Some of it is gruntwork; creating the class, getting headers & dependencies set up; building the UI using a design tool. This is mostly monkey-work, and that's why bad programmers can get to 90%. Getting stuff working is the last 10% of the code that's written, but it's an essentially important 10%.

But once a feature works doesn't mean the work is done. Debugging typically doesn't add lines of code. Refactoring to get stuff working is likely to reduce lines of code. Good coders don't just run their code to see if it works; they test it, too. And they know how to write software that passes tests, and how to write tests that go after edge cases and corner cases.

Going after those edge cases is a mindset. Some programmers have, in the back of their mind, a demon that thinks of malicious calling code. What's the worst that can happen? What if they give me bad data? What sort of bad data is there? Are there possible race conditions that could screw up this process? Good coders have that demon.

"Agile" has turned into a buzzword that many software managers think they need to have. They think writing tests will remove all bugs. But if your tests don't test the right stuff, then your product will still have bugs - it will just take live testing by a QA group to find them. There's good practices in agile testing, but TDD won't get rid of bad programmers or make them irrelevant. The guys you want on your team write robust code the first time. That doesn't mean no bugs but it does mean they, as a habit, look for edge cases.

#4 Features

 I think somehow it has become verboten to discuss intelligence. Yet software is one of the few areas where intelligence has a very strong effect on productivity. Smart programmers get more done. They are good at solving problems, and they can keep track of several things at a time. If they need to keep that "what if" demon running in the back of their mind, the smarter guy will have an easier time at it.

Good programmers get features done faster. Per week, they get more features done.

It's grossly difficult to schedule software development. Agile development, in part, is a response to that. Instead of making up a list of features and then committing to a length of time to get that done, Agile commits to shipping something at a point in time. Some features are easier than others. It's hard to actually measure programmer productivity - but still true that good programmers are more productive.

Shipping Feature-Rich, Robust Software

Software development is about shipping. Guys in academia and research departments can fart around for decades and you can call it good work, but out here in the real world we need to ship software. The more features you have, the better your market position. The more robust your software, the happier your customers will be.

Good programmers make that happen. They write the code, it works when they check it in, and they know how to go after bugs. And they do it all quickly.

Hire those guys; they'll make you rich. :)