|
|
By Nicolas Zinovieff, on May 11th, 2012 You come to be because you want to have something everybody else has, but to “exist” you need to differentiate yourself from your competitors. Said like this, it seems oxymoronic.
There used to be a few reasons why someone would write an application:
- It did something no other application could do
- It took an existing concept/application and added some functionality that was lacking
- It tied a specific interface to a specific service that couldn’t be accessed any other way
Quite frankly, any development that meant more than a few man-hours couldn’t sail if at least one of these criteria wasn’t met. And that was mainly due to one thing: exposure. Finding software for your computer was hard. Of course, services like versiontracker or macupdate was there to help, but a piece of software had to be made, buzzed about and sold by its editor. It had to be “worth it”.
The popularity of the App Store has changed that, for good or for ill. No “respectable” company out there would want to miss on the huge market and public that is composed of iPhone and iPad (and to a lesser extent Mac) users. You just have to have a least a presence there. And the competition of the store is fierce.
So, the companies do what they have to do: at least exist on the app store. With that objective in mind, it’s more a matter of building an image than an app. Therefore, the two axes of communication weight way more than any kind of usefulness. You have to be there (do like everybody else), and you have to be seen there (make yourself known). Essentially, an app can be useful, but an app can exist solely as part of a communication strategy.
For public relation purposes, that more or less precludes any kind of singularity. You want to have at least like all your competitors. Then you have to do better or different in a way that’s not too unnerving, or expensive. And yes, being outrageously shocking is a different way of doing the same thing. Anyone can run naked in the street to grab attention. Changing the way people deal with their daily life is a whole different pie.
I was chatting with a colleague earlier, and he was lamenting that R&D is dead. But R&D serves a different purpose: it’s about long term investment. You pour money and time and effort into building something new without any kind of guarantee that you’ll get a return on your investment. That takes a leap of faith (harder to achieve when you have a responsibility towards shareholders and/or employees) and means (harder to have when you are a freelancer). Therefore it’s really not what most of the paying gigs we get talked into is about.
But I disagree that innovation is dead. Yes, it may seem like that for us freelancers sometimes after the tenth “news pushing” project. But even with projects labelled “do the same as app X, but with, you know, a more ‘our company’ feel”, there are ways to have some leeway and some fun. It could be through the way you make the user interact with your app, the details you want to get back from it to the server, etc… And sometimes, it’s the developer that offers suggestions as to how to make his day less miserable.
Face it, developers: we are responsible for that state of affairs too. Freelancers maybe a bit less than software farms, but the policy of churning out made and re-made apps on the cheap versus being hugely expensive doesn’t promote innovation either. Yes, we have to eat and pay our rent and whatever. But given the ridiculous quotes/conditions some people with innovative ideas get when they talk about them, it’s no wonder these projects are boxed and forgotten.
Personally, I try to “give” at least 15% of my time to projects that seem whacky. Maybe they won’t find their mark, maybe I’ll loose money over them, maybe we won’t even go past the planning phase. And sometimes, I get ripped off. But most of the time, at the very least, I have fun, and I learn something. And the partner/client/prospect/person in front of me can explore fully their idea.
Yes, your idea will be lost among thousands of apps that are there only to exist. Yes, the chances are great that it won’t make you a millionaire any time soon. Yes, finding a willing developer is hard. Yes, it costs a lot of time and money and effort to get anything done. But you know what? If it’s not out there, the chances of it proving to be a good idea or indeed make you a ton of money are precisely zilch.
By Nicolas Zinovieff, on April 13th, 2012 [Dolos]: (anc. greek) Trick, trickery, guile, art of thinking out of the box
[Techne]: (anc. greek) Applied knowledge, craft, as opposed to episteme, pure knowledge of crafts/systems
Our job in technology (hint hint) is to make stuff. But as systems get more complex and our tools… evolve, we get closer to being dolos masters than technicians.
BBEdit just turned 20. It’s changed with the times, adapting to new possibilities and giving me new options and functionality, shedding irrelevant parts and struts to keep lean and efficient. From the day I started earning a living writing stuff (code, courses, and other misc items) to this day, it remained with me, and I fire it up quicker than any other application. If I had any statistic software running, I bet it’d say I spend more time in it than even Finder. Getting used to its way of doing things means becoming proficient in the techne of using it, but mostly, I use it for dolos matters.
On the other side of the ring, Xcode, in its 4th iteration, works more and more and more against me. Using it becomes a dolos process of achieving techne. Most of the scripts and techniques I build over time to optimize my time efficiently gets broken with even the next minor revision of the only way to build mac and iOS application software. Yes, I’ve tried alternative IDEs too, but can’t get them to work as I’d like them to.
To give credit where it’s due, then, thank you so much BBEdit, and happy birthday! I plodded through my professional life knowing that in one way or another you would be able to help me do what I want to do, despite the odds. If I had anything negative to say about you, it would be that you spoiled me for other pieces of software. I kind of expect every single one of the professional tools I use to be as proficient as you are, and I have to say it’s not very charitable.
I am fully aware that a bad craftsman will blame their tools. It’s even a saying around these parts. The thing is, for what I do we don’t have a choice anymore. It’s Xcode or nothing (and the latest version, at that) for packaging applications to be deployed, the latest version requiring the latest version of the OS, and I can’t say I’m impressed by either.
I had to switch to RAID drives for 10.7 to be any kind of fluid, and even then I feel like it’s getting worse. I’m looking for SSD drive big enough to hold everything I need and that ain’t easy, or cheap. Xcode takes a full minute to start up, with 4 2Ghz processors and 8 gigs of RAM. Switching between applications sometimes take up to ten seconds while everything swaps in and out of RAM. And of course, packaging a normally sized application gives me time to make a cup of coffee.
At the same time, I guess I shouldn’t be complaining. Even big companies and the people who would outbid me with customers end up needing my dolos-type of knowledge… Which means that as long as all these tools will be in that frustrating state, I’m going to be well occupied, and incidentally well fed.
And I hope the same applies to you, BBEdit! I’m willing to bet I’ll still be working with you in ten years!
By Nicolas Zinovieff, on April 7th, 2012 Listening to the whole Readability vs Instapaper vs AdBlockers vs The Rest Of The World, from what I can gather, the whole thing is about the role of a middleman. In that particular instance, the people angry at Readability insist on the fact that they ask you to pay for a service that most of the actors are unhappy with or aren’t rightfully informed about. “It’s a scam”, I’ve heard a bunch of times: they insert themselves in-between two actors that have been playing along fine for a while now, propose to make it even better, which is a good grounds for collecting money, by the way, but then mislead people about what they pay for. And that’s where the rubber meets the road…
As a freelancer, there are two models you can follow: you can be in direct interaction with the end-customer, or you can deal through someone (person or company), who will manage the relationship and take a cut.
Managing a client/customer is a skill that is learned. There’s the whole psychological management (mostly revolving around priorities and problems that arise during the development), the administrative stuff (authorizations, papers, negotiations for third party includes), and of course the payment process.
I found out that the quality of my relationship with the middleman has a tremendous impact on my serenity on a project. Basically, both the customer and myself are paying this person to do a job. So, as in every business relationship, the job done and the price paid have to feel adequate.
Here’s a few examples of things I don’t like to see in middleman:
- finder-only: “hey man, I’m just giving you some work! Don’t look at me like I’m going to reorganize that document… Oh and by the way, I’m getting paid 30% of the project total. You know, as a finder’s fee.”
- overbearing: “hey, why are you using CoreData instead of a plain text file? The data’s not that huge… That seems like more work than necessary, right?”. Look, if you want to do the development, go ahead. If you want me to handle it, let me do my job.
- forgetful (usually with payment, obviously): “Sorry, what? Oh yeah that’s right I completely forgot about it! Wait wait hmmmm did we say 6k or 7k? 6k, right? Sure I’ll send an email as soon as I check if the customer paid or not”. This is just the worst. Either it’s stupid, or unprofessional, or a scam.
Now, that being said, over the years, I found some great middle persons to work with. They understand their job as “being in the middle” with every pros and cons any job entails.
Yes some of their chores are problematic, frustrating and aggravating. And if I can (and the relationship is not conflictual), I’ll go the extra mile to help them, because I trust them to do the same for me.
When some friends who want to go freelance ask me about needing middlemen or not, I tend to stay vague. It just all depends… Talking one-on-one with a big company is just too damn time consuming. There are meetings, committees, impossible delays, etc etc etc. If I have only one project to manage at the time, and I don’t feel like giving whatever percentage of the money to a middleman, I’ll do it. But it gets tiresome and frustrating pretty soon. As soon as you juggle with several projects, having someone (or a bunch of someones) to deal with the daily life of consumer relations becomes more and more of a comfort.
So basically, if you are a lot better at talking to machines than to humans, and lack the time to hone the skill of business management, don’t bother. Find a decent, honest, and nice, middle man, treat him/her well and decide on a fair cut, and go for it. Focus on your strength, until you find the time to learn how to do it properly.
Obviously the same applies to designers/graphists/developers/etc… No one is good at everything. And it’s fair to pay for a skill you don’t have, and use to make money.
PPSN: the same applies to software used to make money, obviously. Pay the damn license.
By Nicolas Zinovieff, on April 4th, 2012 It looks as if the question of identity is the main one since the beginning of the year.
I got my papers stolen. If you never had to prove who you are without any piece of ID, you just can’t imagine how hard life can be. Proving formally who you are is one of the most underrated and difficult things to do. But managing your online identity (or identities) can be equally challenging.
The current norm on personal identification is having what’s called “a third party confirmation of who you are”: basically, you are issued by someone who can be trusted (the government, your company, whatever) something that they feel adequate to prove who you are, in order to grant you some privileges. Usually, the bare minimum requirements for a decent ID is a picture (recent and recognizable), a name, and some peripheral confirmation items (a number that can be checked in a computer system being the current favorite).
If you don’t have that, well…
Quick (and true) story: right after I got my papers (and credit card) stolen, I went to the bank to withdraw some cash, to, you know, eat and stuff. I had with me the police report stating that my papers were stolen, a couple of bills sent to my full name and physical address, the contract for the opening of the account, and various receipts of transactions I had done in the past with the bank. To no avail. No picture on an ID, no cash. Except, it’s stupid. It’s a lot harder to come up with all the “peripheral” items I had brought with me than with a fake ID. The ultimate failover, after I casually threatened to sue, was to compare signatures. SIGNATURES! Needless to say, I am appalled.
I have no idea how to make the ID system better, but I’ve watched enough spy movies to know that a picture ID and a signature is far from enough to be certain of someone’s identity.
In computers, identity is both easier and trickier.
To log in on an ultra secure computer, there are a variety of high tech biometric ways to make sure you are who you claim to be. Retinal scans, fingerprints, voice patterns, DNA, password, keycard, trick questions, or a combination of these. If you want to have a physical identification process that’s secure, I guess you can do it.
Remote login, now, is a different story altogether. You can send in through the network all of the above, but it means that you have to trust the path the information takes in between, and the path the remote computer takes to retrieve the information it will be comparing the supplied data with. Basically, you have to add another layer of trust: the network.
But I’m talking military grade authentication here. Most of the websites out there rely on a simple login/password scheme. The underlying assumption is that you won’t share those with anyone, and therefore the worst that can happen is that you forgot the code. Oh and that the server won’t be hacked into. Alright, fine, I guess that even with things that store some very personal and sensitive information, it’s enough in 95% of the cases. So let’s put this problem aside for a bit.
I have started playing around with iMessages. What’s cool about it is that the messages sent or received on my mac/iphone/ipad are all in sync. For all intent and purposes, the person on the other side of the screen doesn’t know (and doesn’t care) which of my devices I’m using to communicate. And on my side, I can type a lot faster on my computer, so that saves me some time (and autocorrect frustration), when I’m home, and I can still reply to messages when I’m moving around.
But, what iMessages does is that it aggregates 2 (or more) IDs/addresses and makes it YOU. So my correspondent might receive messages indiscriminately from my phone number or my email address. And I can send messages to any ID I want too (if I know both). What it does is blur the “technical” bits and makes it look like I’m talking to a person.
Of course, I understand the why: whether you send a text message, an email, or a chat message, to someone, in the end you send it to a person. And they may respond through their own choice of communication. And it shouldn’t make a difference. Except, to me, it does.
I won’t say the same things in a tweet or in a blog post (case in point). And I won’t say the same things (or in the same way) in a text message, or an email, or on Facebook (no, I don’t have an account), or in person. Because I think that beyond the problem of identifying a person as a unique individual, the medium through which we express something does tend to add a bias too.
A little example to specify what I’m talking about here: I have some friends in the business. When we’re knocking down some drinks and talk, we can be free of being “like at home”, and talk about projects and problems freely. If I send them an email about some project or problem, it’s in written form, and I have to anticipate all the questions that can arise, as well as keeping in mind that they might show/forward the mail to a third party.
The worst part is that you may generate a different perception of who you are even without lying. Some clients I’ve had a long email conversation with about a project are surprised when they see me in person. I don’t feel like I’ve not been myself at any point of the conversation, but they had a different image in their head anyway. Or people who know me personally will read a tweet or a blog post and be surprised by what I write. And so on and so forth.
Don’t get me wrong, I don’t think it’s necessarily a bad thing. I’m a child of usenet and IRC, and I know quite a bit about anonymity, posturing, and fake IDs. But I’m primarily focusing on identifying someone here. If I get a text message from an unknown number that makes references to personal stuff, it might be someone I know, or someone who’s heard it second-hand, or a stalker. The same goes for an email: if I know the person, or the person who referred that other person to me, my response will be different, especially if it’s for help, or a quote on a project.
All in all, I’ve been pondering about this identification thing for a while now, and I still don’t know how to make it better, or even how our brains process all the peripheral information we get to be able to say “I know who this person is”. But this is the root of the trust tree, and most of my actions stem from this single fact. It kind of scares me when I think about it. All of this hinges on… nothing much really.
PPSN (post publication side note):
The whole UDID thing with the iPhone is a prime developer’s example of what this identity thing is: how does one make sure a user is uniquely tagged?
The easiest way, till now, was to basically say “you = your phone”. Apple has decided that it was not an acceptable way of doing things. I kind of agree. Then again, Apple, my appleid isn’t me either.
By Nicolas Zinovieff, on April 3rd, 2012 The high tech world we live in generates some really high tech expectations.
Whether it’s needed or not, we see countless “features” and “upgrades” being thrown at us, causing for the most part more confusion than anything else. If there is a lesson the humongous sales of iPads hasn’t taught our beloved decision makers, it’s that sometimes simpler is better than more.
Most of the time, a subtle nudge works better than a huge wink, and thankfully, some designers took the hint.
But it seems that flashy now means modern in some people’s minds. Case in point: a very good friend of mine was put in charge of creating from scratch a website for his company. The company deals in service for professionals (read “something most of you, and myself, will never need”). Their business is all mouth-to-ear anyway, so the website isn’t really needed, it’s mostly so that people could look them up if needed.
He worked with some friends of his, very good at designing websites in their own right, and came up with something Apple-y. Clear and concise, no-nonsense, but clearly not really funny either.
This idea got rejected immediately. “Where are all the animations?” and “can we add a little more bang to it, to show that, you know, we’re modern and all?” seemed to be the major reason for rejection.
Now, picture this: you are tasked by your company to find a suitable service provider. You ask a few colleagues and/or friends from the business, you look companies up, and you come up with two possible candidates.
You go on one’s website, it’s clean but contains little except for a list of current customers, and contact information, maybe with a little side of demo/pr.
On the other’s website, you see animations everywhere, it takes a good couple of minutes for everything to settle down, and maybe take you to the place you were looking for: contact and price information.
In all honestly, which is most likely to annoy?
This is something that, as a developer who knows I suck at design, I have to face on a regular basis. For a project, I would get only screens, and not a word about navigation. A beta I would offer would get criticized at length because “the cool flipover double axel animation thingie is not in, yet”. I would have detailed sketches as to wooshing sound effects and glow-in-the-dark animations, but when I ask “ok, but once you are on that screen, you’re stuck, and have no way to go back, right?”, I would get looked at as if I had rabies.
Every once in a while, I have the chance of working with designers who actually think all of this through carefully. And man, does it feel great to have someone who can sometimes say “you know what, I honestly didn’t think that case would present itself, but now that I see it, I’ll think about how to deal with it”, and do so. And as a user, I even agree with the final decision. Talk about sweet. That was the case on that huge Java project I was working on, and given the scope of the project (think small OS), it was a very welcome change in the type of people I sometimes have to deal with.
In my mind, usability should come first, graphics second. This is why for a long time, Linux, while vastly superior in many ways on the technical level to its competitors, could not gain a foothold in the desktop business: unusable by my granny. That’s why some really really cool projects (from a geek perspective) such as automated households don’t really appeal to most people: they know how to use a dial and a button, and fidgeting with an LCD display and a keyboard seems over-complex. Even if in the end, they won’t have to touch the thing ever again.
If you are thinking of a new and wonderful project, think about 3 major factors before handing the making to somebody:
- the user needs to find what he/she is looking for in less than 20s, or at least understand how to get there in that time frame. (depth)
- do at least a rough storyboard of the navigation. Where do you start? Where can you go from there? Should you be able to go back, or forward only? Repeat. (width)
- “animations” is cool. But only if it highlights a feature you want to bring forward, draws the attention towards it, never away from it.
Now, I’m only a developer. I have no track record in design or graphics. But after a decade of writing code, I start to get a sense of what the user wants. And if a developer can, you can too.
By Nicolas Zinovieff, on March 28th, 2012 Every so often, you get a tremor of a starting troll whenever you express either congratulations or displeasure at a specific SDK, language, or platform.
Back in the days where people developing for Apple’s platforms were very very few (yea, I know, it was all a misunderstanding), I would get scorned at for not having the wondrous MFC classes and Visual Basic and the other “better” and “easier” ways of having an application made. You simply couldn’t do anything remotely as good as the Windows equivalent, because, face it, Mac OS was a “closed system”, with a very poor toolbox, and so few potential users. But hey, I was working in print and video, and MacOS had the best users in both fields at the time. And the wonders of QuickTime… sigh
Then it would be a ProjectBuilder versus Codewarrior (I still miss that IDE every now and then…). Choosing the latter was stupid: it was expensive, with minimal support for NIBs, was sooooooo Carbon,… But it also had a great debugger, a vastly superior compiler, and could deal with humongous files just fine on my puny iBook clamshell…
Once everyone started jumping on the iOS bandwagon, it was stupid to continue developing for Mac.
Every few months, it’s ridiculous to develop in Java.
There seems to be something missing for the arguments of every single one of these trolls: experience.
Choosing a set of tools for a task is a delicate thing. Get the wrong language, IDE, library, for a project and you will end up working 20 times as more for the same result. Granted, you can always find a ton of good examples why this particular choice of yours at that moment in time is not ideal. But that doesn’t mean it’s not good in general.
“QuickTime is dead”, but it’s still everywhere in the Mac OS. “Java is slow” is the most recurrent one. Well for my last project I reimplemented the “Spaces” feature in Java. Completely. Cross platformly. And at a decent speed. I’d say that’s proof enough that, when someone puts some care and craft in his/her work, any tool will do.
It all boils down to experience: with your skillset, can you make something good with the tools at your disposal? If the answer is yes, does it matter which tools you use? Let the trolls rant. The fact that they can’t do something good with this or that platform/tool doesn’t mean no one can.
By Nicolas Zinovieff, on March 15th, 2012 In our personal lives, we all had a “cup is full” moment, when the extra annoying bit of comedy from a relative makes us leave the room, or something like that. Fortunately, this is absolutely not what I want to talk about.
For the past few days, I’ve been struggling with tiny things that make my mood swing even faster than driving in Paris (lovely sights, homicidal drivers): the computer doing what it was programmed to think is best.
Dear developers: what’s best for you (or your boss) is not what’s best for me, or every single customer out there. Stop second guessing me.
It all started with the keyboard selection. I think that’s cool that different applications can have different input methods: I had to type things in Russian in Numbers, while my terminal supports pretty much only ASCII, and I need the character viewer in Pages. So far, so good. Then it went down to hell pretty fast. Because at one point in a modal system frame (belonging to some base process, I guess), I showed the keyboard viewer, it popped up (and never out again) every single time a modal window appeared. Closing it before the modal window didn’t change a thing. For some reason, I needed my keyboard on screen pretty much at all times. The solution? Remove the keyboard and character palettes from the input sources for a while. That way it can “forget” about it. Sheesh.
Then I realized every single website I went to with embedded google widgets (calendars, whatever) would show it in French. Because, well, I live in France. That’s nice to try and match my native language, but the language the browser is set to might be a better indication, or the language of the page the widget is embedded in. Because It feels weird to have to switch back and forth all the time between languages, even when you’re fluent in all of them.
Then there obviously is the nagging restore on open. Nice concept, I really like the idea. But there are programs that make it unbearable: The simplest one is Preview. So I receive a document (invoice, photo, graphics for an app), I double click on it to see it. Then I quit the application. Next time I double click something, it loads all the ones I didn’t close before, and adds them to the same window. So you’re showing some concept art to a customer, and he sees the bill you forgot to close… Or Preview takes 2 minutes to load because you were reviewing a 200 pages document. And don’t get me started on Xcode.
And finally, the “shared search string”: you look for something in a web page on Safari, and that’s supposed to mean you’ll be looking for the same terms in every single application? Replacing the grep search term you so painfully assembled? Gimme a break!
Let me be clear, I think all these ideas have merit. I like it that they are available. But if the user (i.e. me) has to go the extra mile to undo an automatic feature pretty much every single time, it could mean that there should be a way to customize the behavior and let the user decide if he wants the feature on, or not. Right?
By Nicolas Zinovieff, on February 29th, 2012 Following up on debugging innuendos, here’s an example of scratching your head for something apparently stupid.
Working on an iOS project, you need the simulator application a lot. So I was just working on a somewhat huge project when (seemingly) out of the blue, the simulator stops working.
Launching it manually makes it crash, launching it through Xcode only yields in a completely black window.
No worries, just delete the simulated contents (through the “Reset Contents” menu item), and try again.
No go.
OK then. Delete the simulated contents manually (from ~/Application Support/iPhone Simulator/).
No go.
Aaaaaaargh. Delete the preferences, the caches and the simulated contents, and try again.
No go.
Breathe. Call up a friend, and chat for a bit about nonsense and then pop the question. “Just reinstall the devtools, man”. Except it’s a long process. But I’ve wasted an hour already, so…
Reinstalling on top of an existing installation (same version): 20min and… No go.
De-installing by trashing the Developer folder, reinstalling: 30min and… No go.
Maybe something wasn’t uninstalled properly. Use the De-installer script, and reinstall: 40min and… No go.
Alright… Ping a friend at Apple, convey your will to hang yourself with the last non-wireless mouse you have, and whine a bit. “Reinstall the OS, man”. Yea well. No, I have to draw the line somewhere.
So what’s left? Facts:
- It runs well on another session on the same mac
- It runs fine on another computer with exactly the same setup (OS/Tools/Project)
- It crashes on a weird exception: [__NSArrayM insertObject:atIndex:] : object can’t be nil.
- I haven’t installed anything new, so it has to be something from before that got corrupted somehow, that can’t be the tools (reinstalled), the prefs (reset), or the contents (ditto)
So digging a little further, it’s happening when the application loads its main nib. It’s gotta be something inserted in a menu, right? As there’s nothing else left in the contents…
So, firing up Terminal it is then. Then use the “fs_usage” command to figure out after which one of the files it’s loading that the app crashes. It links back to the MainMenu.nib. Not a great help.
Code injection (loading a new category that would supersede __NSArrayM’s insertObject:atIndex: selector, in order to nil-proof the loading) is out of the question with macos applications, so it’s assembly-reading all the way.
Breaking on the exception (catch throw in gdb, but you have to set it after you’ve hit a breakpoint, though) lets me examine the stack at the time of crash, to figure out what the arguments might be. Obviously, it is “nil”, so no help there. Got to figure out a way to break on a “clean” call to that function just before the exception. Ideally, breaking on the previous insert in the same function that worked well.
Let me just say that this can’t really be done.
And then, the click moment: why don’t I print out “self” to see what’s already in there?
Thought breeds deed, and the array is a list of process names. Obviously not every process, since another session works fine, so it must be the list of user processes. Hold on, it seems more complicated than that. It’s a list of user processes and their children, even if they are run with a setuid.
And, like that, the solution is found: I had a disk repair going on (with Media Scanner, the best bad blocks utility out there). Unfortunately, it appears that this process either doesn’t have a bundle id or a name in the process list, or something that yields a nil name.
So, to sum it up: I’ve been stumped a whole day because Apple’s iOS Simulator makes a list of all running processes on my mac before starting up (list that incidentally doesn’t show up anywhere in the interface) and doesn’t like one of them, which is totally unrelated to development anyway.
Two words:
Good
Grief.
By Nicolas Zinovieff, on January 8th, 2012 Back in the blissful days of iOS4, the size you assigned to ints in you model was blissfully ignored: in the SQLite backend, there are only two sizes anyway – 32bits or 64bits. So, even if you had Integer16 fields in your model, they would be represented as Integer32 internally anyway.
Obviously, that’s a bug: the underlying way to store the data shouldn’t have any impact on the way you use your model. However, since using a Integer16 or an Integer32 in the model didn’t have any impact, a more insidious family of bugs was introduced. The “I don’t care what I said in the model, it obviously works” kind of bug.
Fast forward to iOS5. The mapping model (the class that acts as a converter between the underlying storage and the CoreData stack) now respects the sizes that were set in the model. And the insidious bugs emerge.
A bit of binary folklore for these people who believe an integer is an integer no matter what:
Data in a computer is stored in bits (0-1 value) grouped together in bytes (8 bits). A single byte can have 256 distinct values (usually [0 - 255] or [-128 - 127]). Then it’s power-of-two storage capacities: 2 bytes, 4 bytes, 8 bytes, etc…
Traditionally, 2 bytes is called a half-word, and 4 bytes is called a word. So you’ll know what it is if it seeps in the discourse somehow.
2 bytes can take 65636 values ([0 - 65 635] or [-32 768 - 32 767]), 4 bytes can go much higher ([0 - 4 294 967 295] or [-2 147 483 648 - 2 147 483 647]). If you were playing with computers in the mid-to-late nineties, you must have seen your graphic cards offering “256 colors” or “thousands of colors” or “millions of colors”. It came from the fact that one pixel was represented either in 8, 16 or 32 bits.
Now, the peculiar way bits work is that they are given a value modulo their maximum width. On one bit, this is given by the fact that:
It “loops” when it reaches the highest possible value, and goes to the lowest possible value. With an unsigned byte, 255 + 1 = 0, with a signed byte, 127 + 1 = -128. This looping thing is called modulo. That’s math. That’s fact. That’s cool.
Anyway, so, in the old days of iOS4, the CoreData stack could assign a value greater than the theoretical maximum for a field, and live peacefully with it. Not only that, but you could read it back from storage as well. You could, in effect, have Integer16 (see above for min/max values) that would believe as an Integer32 would (ditto).
Interestingly enough, since this caused no obvious concern to people writing applications out there, some applications working fine on iOS4 stopped working altogether on iOS5: if you try to read the value 365232 on an Integer16, you’d get 37552. If your value had any kind of meaning, it’s busted. The most common problem with this conversion thing is the fact that a lot of people love using IDs instead of relations. You load the page with ID x and not the n-th child page.
So, your code doesn’t work anymore. Shame. I had to fix such a thing earlier, and it’s not easy to come up with a decent solution, since I couldn’t change the model (migrating would copy the truncated values, and therefore the wrong ones, over), and I didn’t have access to, or luxury to rebuild, the data used to generate the SQLite database.
The gung-ho approach is actually rather easy: fetch the real value in the SQLite database. If your program used to work then the stored value is still good, right?
So, I migrated
NSPredicate *pred = [NSPredicate predicateWithFormat:@"id = %hu", [theID intValue]];
[fetchRequest setPredicate:pred];
NSError *error = nil;
matches = [ctx executeFetchRequest:fetchRequest error:&error];
to
NSPredicate *pred = [NSPredicate predicateWithFormat:@"id = %hu", [theID intValue]];
[fetchRequest setPredicate:pred];
NSError *error = nil;
matches = [ctx executeFetchRequest:fetchRequest error:&error];
// in case for some reason the value was stored improperly
if([matches count] == 0 && otherWayToID.length > 0) { // here, I also had the title of the object I'm looking for
int realID = -1;
NSString *dbPath = [[[[ctx.persistentStoreCoordinator persistentStores] objectAtIndex:0] URL] absoluteString];
FMDatabase* db = [FMDatabase databaseWithPath: dbPath];
if (![db open]) {
NSLog(@"Could not open db.");
}
FMResultSet *rs = [db executeQuery:@"select * from ZOBJECTS where ZTITLE = ?", otherWayToID];
while ([rs next]) {
realID = [rs intForColumn:@"zid"];
}
[rs close];
[db close];
if(realID >= 0) {
pred = [NSPredicate predicateWithFormat:@"id = %u",[identifiant intValue]];
[fetchRequest setPredicate:pred];
error = nil;
matches = [lapps.managedObjectContext executeFetchRequest:fetchRequest error:&error];
}
}
In this code, I use Gus Mueller’s excellent FMDatabase / SQLite3 wrapper
Obviously, you have to adapt the table name (z<entity> with CoreData), the column name (z<field> with CoreData), and the type of the value (I went from unsigned Integer16 to unsigned Integer32 here)
Luckily for me (it’s still a bug though, I think), CoreData will accept the predicate with the full value, because it more or less just forwards it to the underlying storage mechanism.
Hope this helps someone else!
-nz
By Nicolas Zinovieff, on January 2nd, 2012 We definitely live in strange times. The infamous French law named Hadopi was supposed to give the French government a whole new range of options to deter and sanction illegal copies of licensed material.
I’m not up to speed in all the minutiae of the legal procedures and stuff, but the base rules were thus:
- Some guy in some office with a license to hunt pirates down (but apparently not a cop, whose job it should be) peruses the web to find the IP of your computer participating in an illegal download.
- You get sent an email saying close to nothing except that your IP has been flagged for further investigation.
- You get a hardcopy of the email through the postal system
- If you are flagged again (or maybe not next time but after the third time or whatever, I’ve always been hazy on the details), your internet connection is shut down, and you might (or might not) see the cops at your door some time later.
Now, this mess has been up and about for a couple of years. And it’s dying a slow death, having cost taxpayers millions.
Why?
Because, apparently, the people at the head of this brand new agency get their seats for 2 years and someone forgot to renew the mandate of put other people in their places. Since the agency has no legal jurisdiction if the quorum can’t be satisfied, the whole thing just can’t legally work anymore.
It sounds nuts, doesn’t it? Unfortunately for our French pride, and until the murky waters can be cleared, it seems to be true.
And that’s only the tip of the iceberg, albeit arguably a summit in crazy stupidity.
This legal system (the agency and the laws to back it up) are what we call in the tech trade clearly “ad hoc”. It’s jumbled up together without any real plan, strategy or even common sense. To the people who actually understand how bits and bytes move around, it’s just (and I quote) “crazy bat-shit stupid”.
First off, since only the IP can be flagged, the law stipulates that if you get hacked and someone uses your network to do something illegal, it is somehow your fault. I am technically conversant, and I could probably spot some downloading activity going on through my WiFi network, but I live in a very dense area packed to the brim with computer students. That, plus the fact I willingly give authorizations to my visiting friends means that I wouldn’t bet anything on the safety of my own network. So how could someone who doesn’t even know how to change the fricking password on the WiFi relay do anything about it?
But it doesn’t stop there. Your IP has been flagged, but there’s no proof you’ve been engaged in an illegal activity until some duly appointed law enforcement agent inspects the contents of your hard drive. That means invading privacy in the name of justice, which requires a warrant. In order to get a warrant issued, you have to find a reasonable and plausible cause. In order to get that, you need to have something like a listing of the hard drive, because, frankly, “hey I think some bytes went towards this computer” may be enough in a movie, but in real life, suspicion isn’t proof. I don’t even know how they worked a loophole around that plausible cause in any case, but I guess it’s not such a done deal as they seemed to indicate when the new law was pushed through everyone’s throats.
And then, of course, there’s the official chitty. If memory serves, a warning has to be acknowledged to be acted upon. You can’t say “it’s the third time this guy has been warned” unless you have a proof that the piece of paper has been handed to the person. Theoretically, this is done through a receipt. A friend of mine got the email, but not the piece of paper. He never signed any receipt either. So, legally, he never got it. Is that tricky or what?
In the end, the only person that has any kind of certainty (for a given value of “certain”) as to anything in this process is the guy who flagged you in the first place. He has done his job properly, noted something and pushed it down a pipe.
I don’t know if it’s the case everywhere in the legal system, but I know for a fact that for circulation-related tickets and fines, the name of the officer who flagged the unlawful behavior has to put his name down. For speeding ticket where the flagger is a camera, you have its serial number on the ticket. And I’m waiting to be convinced that, somehow, it’s not the case in every legal procedures in the country.
I’ve read the mail, it is a funny thing to receive in and of itself. There is nothing on it that identifies the person who flagged the deed and initiated the procedure. If memory serves, there’s a date and a time of the alleged perpetration, but that’s it. Shady huh?
So the whole thing starts to smell, doesn’t it?
I’ve said it and I stand by it: piracy will always be around. There is no way to eradicate it totally, just like any other (more spectacular) kinds of crimes. By ridiculing the whole anti-piracy rhetoric this way, to my mind at least, they just make it even more OK… “Hey, even the government can’t do anything about it, so, who cares?”
The key lies in education. If the end user has good motives for buying licensed material (because he likes it, sees the just price for it, can afford it, and has easy access to it), he will. There’s no way that an abstract crime can be avoided in this fashion (no one infringed on any physical, tangible, integrity – there is no trace; no one has less money that they started with; everything is close to anonymous). You have to somehow make it real to the person who’s not supposed to commit it. Physical injury is real. Anyone can relate to that. Therefore it can be a crime, given a set of rules. Ditto for theft. Piracy, when it’s done well, leaves no trace, only actual sales figures that are lower than projected figures. How real can that be to warrant punishment?
Not enough.
So, time to put together positive reinforcement that will simply make piracy obsolete. Because it hurts someone you could like. Because piracy is uncool, for losers. Because pirating something is so much more difficult than getting a clean copy.
|
|