[Xcode] IPA Generation Broken, Again

It happened before and shall happen again: xcrun PackageApplication doesn’t work anymore.

The whole process isn’t meant for contractors

Let’s face it, Xcode is getting better at the coding part, but the signature / IPA generation is “streamlined” for the App Store, which in turn is under a lot of assumptions that I’ve mentioned here in the past. Since the last time, the heavy push for storyboards (oh, the tasty git conflicts), and the weird quirks of swift haven’t really improved things. Dev tools should be as flexible as possible, because they are meant for devs.

Anyways, 8.3 broke the “easy” IPA generation that everyone was using. It was especially important for Hudson/Jenkins continuous integration and beta deliveries. No, relying on the Organizer’s UI doesn’t work, because more often than not, you want automation, and Xcode is less and less automatable.

PackageApplication is gone

It worked for a while, then you had to remove a part of the entitlement checking, but now it’s not there anymore. So… no more Hudson builds?

Fret not! The one-liner may be gone, but we have a heavily convoluted multi-step export process in place that does the same!
(Imaginary tech support person)

The idea is to replicate the UI process:

  • generate an archive
  • click export an IPA
  • select a bunch of signature and type options
  • rename all the things it exported (you usually want the build number/version right)

Believe it or not, some of these are actual xcodebuild commands. But the argument list is… errrrr, weird, if you’re used to Linux and server stuff. So, no, in the following, it’s not a mistake that there’s only one dash. You have been warned.

Gimme!

There are two pieces to the export thing : a plist containing what you would type/click in the UI options at the end of the process, and a script that chains all the necessary actions together. I tried to piece together various sources into a coherent whole, but it’s a dev tool and your mileage may vary. Also, because it’s intended as a Hudson build script, it takes the version number as argument and outputs what I would upload to the beta server in Outfiles. Again, adapt it to your workflows.

The plist:

< !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>method</key>
    <string>development</string>
    <key>teamID</key>
    <string>TEAM_ID</string>
    <key>uploadBitcode</key>
    <true></true>
    <key>uploadSymbols</key>
    <true></true>
  </dict>
</plist>

Remember to use the correct TEAM_ID in there.

The script (takes the version as first argument, may break if none is provided):

#!/bin/bash
 
APP_NAME="Insert app name here"
SCHEME_NAME="Insert scheme name here"
CONFIGURATION="Insert configuration name here"
 
ARCHIVE_DIRECTORY=Archives
OUT_PATH=Outfiles
 
#change as needed
SDK=iphoneos10.3
 
echo "Cleaning previous build"
 
#clean
xcodebuild -sdk "$SDK" \
-scheme "$SCHEME_NAME" \
-configuration "$CONFIGURATION" clean
 
echo "Creating Archive"
 
#archive
xcodebuild -sdk "$SDK" \
-scheme "$SCHEME_NAME" \
-configuration "$CONFIGURATION" \
-archivePath "$ARCHIVE_DIRECTORY/$APP_NAME-$1.xcarchive" \
archive
 
echo "Creating IPA"
 
#export ipa
xcodebuild -exportArchive \
-archivePath "$ARCHIVE_DIRECTORY/$APP_NAME-$1.xcarchive" \
-exportPath "$OUT_PATH/" \
-exportOptionsPlist exportIPA.plist
 
#name files and dSYMs
mv "$OUT_PATH/$APP_NAME.ipa" "$OUT_PATH/$APP_NAME-$1.ipa" 
cp -rf "$ARCHIVE_DIRECTORY/$APP_NAME-$1.xcarchive/dSYMs/$APP_NAME.app.dSYM" "$OUT_PATH/$APP_NAME-$1.dSYM"
cd "$OUT_PATH"
zip -r "$APP_NAME-$1.dSYM.zip" "$APP_NAME-$1.dSYM"
rm -rf "$APP_NAME-$1.dSYM"
cd ..
 
#optionally
# rm -rf Archives

As usual, use with wisdom ;)

Final Thoughts

It’s not that the system is bad, per se. It actually makes a lot of sense to have commands that mirror the GUI. But the issue is, for a long long long long time, automation hasn’t been about simulating clicks. Since you don’t have the UI, it makes even more sense to have shortcuts in addition the GUI counterparts

  

Some More Adventures in Swiftland

Last summer, I tried to learn new tricks and got some small success. Because the pace at which Swift 3 is changing finally settled a bit, I decided to finish what I set out to do and make SwiftyDB both up to date with the latest version and working on Linux.

The beginning

In August, SwiftyDB was working fine on MacOS but, while it compiled fine, it didn’t on Linux for a variety of reasons.

Swift was flimsy on that platform. The thing “worked”, but caused weird errors, had strange dependancies and was severely lacking stuff in the Foundation library. The version I had then crashed all the time, but for random and different reasons, so I decided to wait till it stabilized.

With Swift 3.0.2 and the announcement that Kitura was to become one of the pillars of the official built-in server apis (called it, by the way), I figured it was time to end the migration.

The problem

The main issue is that swift for Linux lacks basic things Foundation on the Mac has. I mean, it doesn’t even have NSDate’s timeIntervalSinceReferenceDate… But beyond that, the port lacks something that is truly important for the kind of framework that SwiftyDB is : introspection.

The typechecker is the absolute core of Swift. Don’t get me wrong, it’s great. It forces people to mind the type of the data they are manipulating, and throws errors early rather than late. But it comes at a cost : the compiler does all kinds of crazy operations to try to guess the type and too often for my tastes, fails miserably. If you’ve ever seen “IDE internal error” dialogs in XCode, that’s probably the reason.

But even if it worked perfectly, data manipulation that’s needed to get rows in and out of the db requires either to work with formless data (JSON) or to have a way to coerce and map types at run time. And boy, swift doesn’t like that at all.

So, SwiftyDB handles it in a hybrid way, passing along dictionaries of type [String : Any] and suchlikes. It’s kind of gross, to be honest, but that’s the only way this is going to work.

But that was kind of solved in August, albeit in a crash-prone way. What was the issue this time?

The swift team made huge strides to unify MacOS and Linux from an API point of view. If you read the doc, it “just works”, more or less. And that’s true, except for one tiny little thing : toll-free bridging.

Data type conversion

Swift, as ObjectiveC before it, deals with legacy stuff by having a toll-free bridging mechanism. Basically, to the compiler, NSString and String are interchangeable, and will use the definition (and the methods) it needs based on the line it’s at, rather than as a static type.

Something you surely know if you’ve done any kind of object oriented programming, typecasting is hard. If String inherits from NSString, I can use an object of the former type in any place I would have to use the latter. Think of the relationship between a square and a rectangle. The square is a rectangle, but the rectangle isn’t necessarily a square. It’s an asymmetrical relationship. And you can’t make it work by also having NSString inheriting from String, because that’s not allowed for a lot of complicated reasons, but with effects you can probably guess.

So, how does this toll-free bridging work? By cheating. But that’s neither here nor there. The fact is that it works just fine on MacOS, and not on Linux.

A solution

The easiest way to solve that is to have constructors in both classes that take the other as a parameter. And that’s the way it’s solved on Linux. True it’s a bit inelegant, and negates most of the “pure sexiness” that swift is supposed to have, but what are you gonna do? This, after all, is still a science.

Once those extensions are in place, as well as a few replacement additions to the stock Foundation (such as the infamous timeIntervalSinceReferenceDate), and a few tweaks to the way the system finds the SQLite headers, everything finally works.

Use it

As I said before it’s mostly an intellectual exercise, and a way to see if I could some day write some serverside stuff, but in the meantime it works just fine and you can find it here. Feel free to submit pull requests and stuff, but as it is, it works as intended : swift objects to sqlite storage and vice versa.

As usual, if you want to use it as a swift package, just use:

.Package(url: "https://github.com/krugazor/swiftydb", majorVersion: 1, minor: 2)

  

[Xcode] Broken IPA Generation

As of Xcode 6.0.1, you can only generate an IPA with a certificate/provisionning profile pair that matches a team you are part of (it offers only choices present in your Accounts preference pane).

Before ranting about why this this is stupid as hell, here’s a workaround:

xcrun -sdk iphoneos PackageApplication [path to the .app] -v -o [path to the ipa] --embed ~/Library/MobileDevice/Provisioning\ Profiles/[profile to use] --sign "[matching developer NAME*]"

NAME is the name that appears in the popup menu in your xcode build settings, not its ID

After a somewhat lively discussion on Twitter about that, two things:

  • I know Apple would prefer that developers are organized in teams managed on their servers. It’s just not practical for a lot of them, and there’s even a few good reasons not to go that way
  • It’s stupid to have that drastic a change, when 3 weeks ago, the official way of having a third-party developer generate IPAs for your company was to give him a p12 and a .mobileprovision and let him do his thing, and to not warn people about the change

For those of you who don’t know how development of a mobile application works, yet, here’s a quick run down.

A customer contacts me for a development. We agree on a timeframe and a price. I write the code, provide them from time to time with testable betas. When we agree it’s finished, I give them the final IPA for putting on the store and we call it a day.

Providing betas and giving an IPA for the App Store work exactly the same: a binary is produced, which is put in an IPA (kind of installer package for iOS), then that IPA is signed, and transmitted. On the other end of the wire (be it the customer or the App Store), the IPA is decompressed, the signature checked for validity (by app ID, device, and status of the apple account), and the app can be run or put on sale.

In that scenario, if I use my certificate, I have to enter the device IDs the customer will test the app on, of which my developer account allows for 100, in total. So if I have 10 customers with 10 devices a year, I can’t work anymore. So, most of the time, the customer has to provide the relevant information for me to give access to the betas, and of course, since they’re releasing it under their own name, the relevant information to produce the final version, which is a different pair of keys.

So far, so good, all they had to do up until now was give me a couple of p12 (key archives) and the corresponding profiles, and manage themselves the test devices, the release, etc.
It allows whoever’s in charge to retain access and knowledge about what the company is doing. Does that person want me to see they are also working on a concurrent product to something I’m doing for somebody else? Of course not. And there’s no reason to give me that kind of access. Oh and if the customer wants to prevent me from using that certificate again, all they have to do is revoke it.

The new way of doing things is to have the customer invite the developer in the team (in the Apple sense of the term), which gives the developer access to every piece of information under the sun (even when we can’t use it directly).

This is part of an ongoing cycle of making life difficult for contractors. We always have to find workarounds. The idea that almost every ios/mac developer out there is writing code for the structure they belong to, who will then release it in their own name for the general public is ludicrous. It hinges on something that has been gnawing at me for years: the idea that code and binary are the same thing, and is what I’m selling.

That idea is false. When you get Unity3D for your game development, you DO NOT GET THE CODE. For Pete’s sake, we don’t get the code of the OS we are developing on! The idea that when a developer is hired, the customer automatically owns the code is one of the many fallacies I have to deal with on a monthly basis. You hire a developer for his/her expertise first, and foremost. It might be then applied to internal code, which the dev won’t own in the end anyways, or to a newly minted piece of code which might or might not be given with the ability to use said code as part of something that has value. It is a separate item on the negotiation list.

I might delve into the pros and the cons of giving out your source code with the binary in a later post, but let’s get back on topic.

If, like me, you don’t always give the code with the binary to the customer, you’re screwed. Of course they won’t give you access to their company’s secrets by adding you on the team, if they don’t want to. And, obviously, you can’t release the binary under your own name for a customer who wants an app.

Please give me back a way to sign IPAs for customers, directly from my IDE.

Thank you, and sorry for ranting.

  

[iOS7] Woes Unto Me, For I Am Undone

While I’m waiting for a full restore of my iPhone that will hopefully get me to a usable state again, there’s a couple of things you should know about iOS programming that has subtly changed.

First off: I like the new interface. I like the new OS. So this is not a mindless rant.

[UIKit]

UIKit has never been threadsafe. Ever. This is why we got used to performSelectorOnMainThread back in the pre-block days, then dispatch_async. The non-threadsafety of UIKit is a total mystery to me, seeing that I can change text in labels, images, and the like, mark the views as dirty, and then the main GUI should take care of the updates however long afterwards. That being said, Android does the same, so there must be a technical reason I’m not seeing. However, Android doesn’t even let me change anything. It’s an immediate exception at runtime. UIKit, on the other hand, lets me do pretty much anything I want, then crashes with a cryptic message, when there is one. After digging and step-by-step debugging, I usually find that what I assumed runs on the main thread, does not, in fact.

But that’s the kicker, right here. Up till iOS6, some conventions (or habits to be more accurate) led me to believe that this callback or notification would always be called on the main thread, thus not forcing me to use a very performance-expensive dispatch block. And then… it changes. The app starts behaving erratically, when it doesn’t outright crash. And debugging that erratic behavior is difficult, because it’s basically a race-condition. It could work just fine on an iPhone 4 but not on a 5, and vice-versa.

For a new codebase, I guess the problem doesn’t arise as much, but for us developers who work on older projects, sifting through thousands of lines of code to figure out which one causes that is time consuming, to say the least.

Case in point : navigation controllers. They used to be somewhat thread-safe, pushing and popping being stacked and executed one after the other. Of course, every now and again, you would have to tweak a little bit, make sure some essential data was loaded before pushing the next one, but nothing illogical.

In iOS 7, it’s totally asynchronous and unstacked. And unless you setup a delegate to make sure you detect the end of the animation, you can end up in very dark places. As soon as you have a more complex navigation than simple tree walking, something that worked reasonably well till now becomes very hard to maintain.

Let’s say I have a custom navigation bar that reflects some general data (ie not just a title with the name of the current screen you’re at). Now lets imagine some scenario where when you change something in one of the leaves of your navigation tree it requires a change in another leaf, where the user has to input something. You can say, for example, that you have a weather app, and in one leaf you have the general area of interesting data (wind, hygrometry, whatever), and in the other the units you want to use. Changing from one to another requires a change of units. So, naturally, you want to pop the view controller and push the units one. Except now, you can’t do it too fast. You have to wait for each animation to complete before taking the next action. And you really shouldn’t try to change the title while the animation is running either. (yes I know you could set the navigation hierarchy directly, but my rebuttal is the same as the one given afterwards)

And I hear someone say “well it’s easy, you have the two delegate methods for the navigation controller, so just use it”. Yeaaaaaaaaaah. Weeeeeeeell… The nav controller delegate has to be known at a higher level than the views you will push and pop, right? So basically, the app delegate would be the nav delegate. So the app delegate has to know about the underlying structure and the navigation paths of the whole application? Sorry, I do object oriented programming, I have no intention of having all my view controllers as instance variables of my delegate with a huge switch every time there is pop animation to determine whether I should wait for it to finish or not.

What would be a good alternative then?

  • If I had a notification I could subscribe to, that’d be swell. And that’s what I implemented at the higher level. But it’s a hack.
  • There could be a lock, too. [UINavigationController waitForAnimationToEnd] for instance.
  • Or a bool telling me whether the nav controller is in transition or not.
  • Hell, even an exception would be better than just putting the app in an uncertain state. At the very least I could break on it to find which one of my thousands of lines should be scrutinized.

Going the multi-app, multi-threaded, asynchronous, route, is fine by me. But we have to have the tools to do it properly. Even viewDidAppear is not a guarantee that the animation is done and changing the title or pushing a new view controller on the stack won’t give us a nice Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.. What did I do wrong that was perfectly fine up until 3 weeks ago? No idea. No exception. No information. Just “hey don’t do that”. Totally Kafkaian as far as I’m concerned, since I just hit on the back button. But now, after this point, any and all navigation related code will crash. And I’ll spend a few hours or even days to figure out why.

[Networking]

For the same reasons, networking (low level networking mostly, but with stuff creeping up sometimes higher) has changed. I can have network connectivity, tested, working fine in Safari, and a socket that connects to nothing while not timing out. Why? How?

Because that, too, has been moved to a new asynchronous mechanism that offers very little help. My NSURLConnection might appear to be doing nothing, but be active enough so that the system as a whole doesn’t deem it a timeout. And since I have no way of peering into its current state, apart from waiting patiently at the delegate points, the net result is that the app looks as if it’s stuck. Which it is, but not UI stuck. Can’t get out of that mode any other way than kill/restart for now.

I wish I had dug enough to give you more information about it, on par with the above UIKit problem, but the truth is it’s been 2 weeks and I still haven’t had the time to figure it out properly. And I have very little hair left. And it’s all grey.

[Conclusion]

I am for all the new changes. I like them, think they make sense, and overall improve and expand the possibilities for us developers. But without insider information as to how the thing works under the hood, we have very little ways of tackling these kinds of bugs. And all of them feel… hacky.

By all means, change the APIs, improve them, etc etc, but also give us the tools to do our jobs properly. Everybody wins if the users are happy.

And I wish I didn’t have to kill Mail so often, which seems to be stuck on the same problems I have. I guess that’s a sign that I’m not alone in my struggle.

  

Who-What-When-Why

Now that I’m almost done with my despaghettification, and for reasons that will become obvious as you read on, I’m kind of wondering about teamwork.

I’ve had good and bad relationships, projects that made it through despite the huge odds (think “organizing events”) or projects that went down the drain pretty fast for unforeseen reasons. I think that despite the common asocial image associated with computer geeks, working with unforgiving machines makes us highly sensitive in some areas of human relationships. To wit, we have to follow a clear set of rules all day long, and it can be really hard to have an interaction in which the rules change constantly, or aren’t completely explainable. I think that deeply ingrained in our daily life is the assumption that given enough time and “debugging”, everything’s 100% understandable.

Most “normal” people, as some of my friends will call them, don’t think like that. They keep adding stuff to the rulebook, such as “when someone higher up in the hierarchy calls, I pick up the phone, no matter what”, or “you don’t say to your spouse that you’d like to go out with your buddies because you want a taste of normalcy once in a while”. True, it’s a primitive form of trial and error-by-being-punished, but they are stupid rules that should be replaced by more generic and sensible ones. You pick up the phone because they have some business with you (but should still be ready to say “Look I have work to do, can I call you back?”), or you behave in such a way that it is normal to spend some time apart from your spouse, and just as normal as it is to spend some time with him/her. Basically, you don’t spring up a new rule on somebody else because you don’t like them sprung on you.

Back to teamwork, I find it hard to work with people who have a different set of rules than mine, especially when we are trying to build something together. I’ve been kind of documenting this for a long while and am curious as to what you guys think about it.

To me, doing a task can always be resumed in a sentence such as this:

This person wants me to do this Nth step like this because of that

And in my decade or so of working, I’ve seen various people focus primarily on this or that part of the sentence. I find I have a better personal relationship with people who share my focus, but can work with them more easily if I “get” what their focus is. If I don’t understand what they are leaning towards, it’s a one-way ticket to hell.

Who

For obvious reasons, who’s doing the asking matters a lot. As a somewhat social species, we don’t feel like putting the same effort into a task for a personal friend or a complete stranger. It is unequivocally true in personal relationships (hence the word personal), but in professional tasks, the who is the gatekeeper, and should not be some kind of thermostat.

If your boss asks you do do something, and you agreed to do it, then it has no more value than if it’s a friend who does the asking, in my mind. The who deals with the accepting the task, not the realization of it.

When I have to deal with co-workers to whom the person doing the asking defines the whole of the effort put into the task, I shiver. Yes, this person is your biggest customer. Yes this person is your boss and could reassign you to toilet duty. Yes this client is the cutest person on Earth. But you have agreed to other tasks as well. It actually serves the relationship to state you’ll do your task the way you think is better, rather than the way this person thinks it should be done.

What

Each and every one of us has things they like doing, and things they hate doing. We tend to procrastinate on things we don’t like to do and perform admirably on things we love. And everything in between, mileage may vary. Same thing as the who, it’s natural and literally built-in our genes. We learn through painful mistakes not to put our fingers in the flames. It gives us most of the “one shot rules” I was talking about earlier.

But the thing is, it’s like the who of the previous section. It acts as a filter for accepting the task or not. Once you agreed to perform the task… well, it has to be done.

One of the people who was supposed to “help me” (aka “do it for me”) with my accounting and stuff was exactly like that. Give him a book on his favorite topic or strike a conversation about it, and absolutely no other work would be getting done. And I know I have myself that tendency that I try to overrule all the time: I like debugging and optimizing and looking at the tiny teenie details, rather than cutting up the PSDs to size. But hey, I accepted the task.

When

Each task has a history, and has a place in a process. Being a developer, most of the tasks I get assigned are the end-of-chain kind. There’s a reason why this tasks occurs now, has to be done by that time and is worded or constrained the way it is.

But rehashing about the timeline over and over and over again bores me. If I have to plug this into that, I do’t really care about all the steps that led to this particular form factor. I mean, I do care about it, but it’s a matter of perspective. I care about it to understand how to perform better, but if it’s not relevant, or I don’t have much latitude in my task, then… why bother.

Why

As you probably guessed by now, that’s what makes me tick, and it does make me tick a little bit too much sometimes. I want to understand why it works or should work in the way it does, because it makes me feel like I’ll write less code, or write code that will integrate better in the grand scheme of things.

The main trouble with focusing on that part of the task is that progress comes in discreet steps. There’s an inordinate amount of analysis and thought that goes in it before a step is taken, then another kind of long pause, etc… It can be hugely frustrating for people who work with me because they’d see nothing moving till all the pieces fit together, and then it all works, as if by magic. And even though I’d be able to explain in great details why I did things that way, we rarely have time for it. So it stays “a kind of magic” that was long-ish to come, and works in mysterious ways.

Kind of conclusion

Being a developer means interacting all day long with an alien way of doing things, and we’re kind of stuck between “regular” humans and unforgiving computers. That means that the human interaction part of work will mostly be evaluated in a similar way: how should I say/write this (syntax), so that the other person (compiler) does what I’d like them to (algorithm). Man, that sounds so nerdy, but I genuinely think that it’s somewhere deep in most work-related conversations I’ve had over the years.

And so, based on that experience and these thoughts, I realized that it takes quite a huge effort to find out what makes other people tick, but once it’s understood, it makes every interaction a whole lot easier. But if the focus keeps changing, the amount of time spent finding out the right “syntax” to talk with somebody about what has to be done becomes too long to be a useful use of time. That’s why some of my co-workers feel they can’t delegate and can’t rely on anyone to help them.

So my advice to anyone dealing with what seems to be an introverted geek, is to find out which part they are more used to dealing with (because they were educated that way or just like it) and make sure your translator is on!

  

The State I Am In

(I hope Belle and Sebastian will forgive me for using one of their wonderful titles for a less interesting piece of mine!)

A month ago, I turned 30. And since everybody told me that it would trigger in me a phase of reflection back on my life, and more importantly where I would go from here on, well it did (surprising feat of mass hysteria and self fulfilling prediction isn’t it?)

Professionally, I’ve been paid for writing code for 12 years. When you think that’s more than a third of my young life, it’s mind boggling. A few days ago, I was talking with a good friend of mine, also in the trade, and we felt… Old.

Think about it: When I went to my first WWDC (last… century?), being a developer was being an outcast, in a way. Forget the old myth of social inaptitude… The fact that 3000 of us gathered to eat, talk, joke, sing and code means that we are just as social as anybody else. But instead of having excellent social skills with people immediately around us, we had social skills with relating to somebody who’s halfway across the world, working with something that has no social skill whatsoever: the computer. Blind to local problems, mostly, but very hot on stuff that is virtual (that you can’t touch).

Funnily enough, now everybody is a geek. My brother keeps in touch with people he hasn’t seen in years through chat services or social networks. He used to chastise me when I spent some nights on IRC or participating in forums on the interpretations of the Snark poem, by Lewis Carroll. These days, he spends  half his leisure time on the ‘net.

In a way, my whole early adult life has been validated in the past couple of years. The comments I got went from “oh, so you spend all your time on a computer, huh? Must be tough to meet girls” to “oh, you are a developer? What cool projects did you work on?”

Most of my “online friends” from the late 90s I’ve kept in touch with, albeit yearly instead of weekly, and most of them are now successful people in their own right, thus contradicting our parents and “real life” friends’ predictions.

But, as the trade got a wider attention, and a wider acceptance, some kind of pollution crept in with it. I remember when my friends got admitted to some computer software school. They were entering a world where 90% of the people they were going to interact with were as geeky, obsessional, curious, or plain weird as they themselves felt.

When I got around to teaching in such a school, I realized it is now a job like any other job: some are in for passion, some are in through need, some are in for the money. About 15% of my students were like I remembered my friends to be at the time they started school.

Small pause: I am not being bitter or conservative or elitist in any way. I just observe the fact that every trade that starts as a hobbyist thing and starts generating business is heading more or less in the same direction: you’ve got to be able to make a living off it. Therefore, profit starts being important. And in the name of profit, compromises have to be made, and that of course includes sacrificing part of the geeky pleasure someone derives from just rising up to a challenge no one else has yet.

In my professional landscape, lines have shifted too. The customer base isn’t just the professionals and the gamers anymore. They are people like my parents, or my friends. The expectations of such a crowd are vastly different from the previous one. And it’s a good thing, mostly. People care about the looks of things, about ergonomy, about tiny details that 10 years ago “real” developers would have scorned at and dismissed like their first pair of socks. Aspiring to better things is good. So in my mind, the level of the demands from the users has rocketed, and it’s thrilling, even though it requires a lot of work. I am no graphic artist by a long shot, but I still need to be careful about the looks of things. New challenge! Yeaaaaah!

However, since the market is a lot bigger, people with appetite for money rather than craft have also taken a big slice of the cake. And that makes me a little bitter.

From personal experience, and from what other people in my position tell me, less than 30% of the people involved in computer projects out there are actually positively contributing to said projects. That includes the manager who takes swift decisions about features and “protects” the craftsmen from the end user/customer, the artist who does the graphics, the beta testers/support people who report bugs in a way the developer can fix it and who interface with users who don’t speak l33t, and the code monkeys.

Let me take a quick example. A few months ago, I was approached to build a piece of software. After a quick phone conversation, followed by a meeting, we started swapping ideas, and talking budget and planning. Then something happened and another company was hired for the job. A 300+ developer strong company, versus me. To what I say “alright, fine, maybe this is a project too big to give to a one man company, no hard feelings”. About a couple of months later, I get a call from the company that was hired in my place. They had just finished the specs and the budget and the planning, and the rest and were looking into hiring me to make the program itself. So, for reasons I don’t think I will ever grasp, the situation was that the same program, with the same features, and probably the same deadline, was to be built at 50 times the cost, and with more people diluting the engineering process.

What happened? Why would any sane person think that this is a much better solution than the original one?

I’ve heard people say it’s the price of insurance: if a big company is paid for the job, they will have the resources to pull it off, even if the lead developer dies suddenly or decides to quit. Fair enough. But does that justify the 50 fold increase?

Let’s say I ask for 10k for the job. Half up front, half on delivery. Now let’s say I disappear halfway, leaving a couple of unfinished betas, but no source code. What do they have?

  • a hole of 5k in the bank
  • a bad experience
  • a lot of design choices and a much better spec that they started with
  • something that exists and can be duplicated or improved upon

 

With a bigger company in front of them, who will outsource to small developers anyway, what they don’t get is a direct access to the developer (usually), a somewhat lax business policy in terms of decision reversal and prices, and the human relationship. Is it really worth all that money? Especially since the risk of going over budget or over deadline is higher with a bigger group of people to handle.

It took me a year to recover financially and “cred wise” from my US attempt. Now that I’ve reinvested time and energy into making a living off my craft, I can see some of the reasons why things work like that. But I can’t really say I find these reasons any good. The number of direct-to-customer links is kind of dwindling, and talking with the middleman, who doesn’t have the same set of priorities as either the customer or myself, is tricky, to say the least.

I thought the advent of iOS apps (small and easy to publish) would change that a little bit, but it doesn’t seem to have that kind of effect. Indies somedays feel like a dying breed. We still are indies in financial terms and in name, but we are not independent anymore. And when we are, it’s tough to make a living off it. It’s a job like any other job.

Question is, now that I’ve done that for more than a decade, what do I really want to do with my skillset?

I can carry on, ranting as I go about the vagaries of my line of work; I can endorse the changes made and become part of the system, at any level; or I can shed it off and move on to a different field, where what I learned may be useful… or not.

I think I need a well deserved vacation ;)