Instabrowser

It’s been awhile since I’ve posted an update, but that’s been due to me working like crazy on a not-so-secret project, Instabrowser.

It’s taken me way longer to get to a releasable version than I thought it would, but it’s finally happened.

Along the way, I learned way more about WebKit and UIWebViews than I ever wanted to know. I’ve got a few posts I could write, but right now, I’m so busy with launch activities I don’t have the time.

Anyways, if you found one of my blogs helpful, the best way to say thanks would be to download Instabrowser.

Happy coding.

UX Rage: Baldur’s Gate: Enhanced Edition for the iPad

baldurs-rage

I was excited about Baldur’s Gate: Enhanced Edition (BG:EE) coming to iPad. I had only heard good things about it throughout the years – Sadly, I missed it the first time around.

But as soon as I spent my $9.99, sat down, and started trying to play the game, a plethora of UX problems jumped out at me. I couldn’t even make it through the tutorial before I was ready to throw my iPad out a window. The game’s design for a touch interface is a usability disaster – it’s a poorly done port of a PC game that didn’t have a great UI to begin with.

While throwing my iPad out a window may have been satisfying, I decided to instead channel that rage into this blog post, which takes a few moments to point out the most egregious UX problems and identify a few possible solutions. As Leeroy Jenkins would say: let’s do this.

Welcome to Icon Hell

If there’s one thing that makes an interface difficult to learn, it’s an overabundance of icons. Labels require no special training or memorization to use, so where possible, it’s a good idea to use them instead of icons.

For the main game view, the millions of of icons on screen don’t bother me. To be able to quickly access many different actions with a minimum of taps, icons are great.

Of course, on a menu screen used for selecting which spells to memorize, is making everything accessible in one tap a priority at all? Nope.

IMG_0131

What does it all mean?

This was the first screen that made me angry with its masses of incomprehensible symbols. Being a fearless iPad user, I tried tapping icons at random. This moved them into and out of my list of memorized spells, but didn’t tell me what they were.

For this screen, it would have been much better to implement it as a table view with the spell icon, spell name and short description shown in a single row. In addition, a giant question mark could provide one-tap access to the full description:

spell-mockup

Unsucking spell memorization in 5 minutes flat. I spent more time coming up with silly spell names than doing the design, and it’s still better that what Baldur’s Gate offers. The spell “Shitty UX Design” does only 1 point of damage to non-designers, but will teleport a designer straight to the 7th circle of Hell.

There are a million other ways you could design this screen to make it suck less. Instead, what we’re left with is indecipherable.

The don’t-call-it-long-press

At some point in trying to select my spells, I tried the long press. After all, it’s never failed me before. I placed my finger down on a spell icon and waited what seemed like an eternity. Nothing happened. Tried it again, thinking I might have missed the small touch target. Still nothing – until I gave up and lifted my finger – and then the spell information appeared. What, a long press that works unlike every other long press? WHY WOULD YOU DO THAT!?

If you’ve ever used any native iOS app, or one of the hundreds of thousands of other apps that happens to implement the long press, it works like this in all of them:

  • You place your finger down on the screen.
  • You wait until a popup appears.

Here’s the experience in Baldur’s Gate for iPad:

  • You place your finger down on the screen.
  • You pick your finger off the screen. Nothing happens, because you only waited .249 seconds when you needed to wait .250 before removing your finger. You curse loudly at the god of technology, Technarius, pull out a stopwatch so you can carefully measure your press time, and try again.
  • You place your giant, meaty finger onto the tiny icon again. This time you wait a good 5 seconds, because dammit, you’re not going to let some arbitrary timer beat you. You hold your breath, lift your finger and… nothing happens because your sausage finger was 1 pixel off of the icon’s hit target. You curse the god of meat, Porkarious, file your fingers down to a manageable size, and try again.
  • You tap and hold as accurately as possible… wait what you think is a long enough time… and lift your finger. You cry tears of joy as you finally learn what a spell does!
  • You switch to Mail and long press reply to bring up the action menu, tap reply all to that company-wide email and send a cat picture. Standard gestures and grumpy cat are awesome!
  • You come back to Baldur’s Gate, and don’t understand why your long press is not working.
  • You remember that Baldur’s Gate uses a shitty, proprietary long-press-that-isn’t-a-long-press just to make you swear at made-up gods and waste your time. DAMN you, Longus Pressicus, god of non-standard UIs!

This goes back to a point I made on Twitter earlier: custom UIs for games are not ok unless you have a really, really, really, really good reason to abandon the wisdom of thousands of man-years of learning on the right way to do human-computer interaction. Baldur’s Gate has no excuse.

My favorite part of emailing a cat picture to your entire company is the inevitable 10 reply alls that say "Don't reply all".

My favorite part of emailing a cat picture to your entire company is the inevitable 10 reply alls that state “Don’t reply all”.

So, uh, what are you guys doing?

This one is so egregious that it boggles my mind that the app was shipped with it.

Basically, if you pause the game, and try to issue commands to your characters, you get either zero or almost zero feedback.

Trying to figure out what changed on the screen after issuing a command is like a shitty version of Where's Waldo. Here, there's just a tiny icon on a character portrait with no indication of which target was selected.

Trying to figure out what changed on the screen after issuing a command is like a shitty version of Where’s Waldo.

Best case: the circle around the monster flashes for a fraction of a second.
Average case: a little tiny icon indicating your next action appears on your character portrait.
Worst case: nothing happens. Literally, nothing. No change in the pixels on your screen whatsoever.

When not paused, if you tap a target, the circle will sometimes change into more of a crosshair. That’s not too bad, though it could be better. It’s still not good.

Here’s one way it could be made a lot better: simply show an arrow from each of your characters to their current target.

Arrows, arrows, everywhere. (Not the stabby kind.)

Arrows, arrows, everywhere. (Not the stabby kind.)

Another way this could be greatly improved: As soon as you select an action, show it in on screen so the user knows what they need to do. As soon as they tap an enemy, display some text briefly that says what they did (targeted imp!) along with making the imp flash and drawing an arrow from the unit to the enemy.

My theory: the UI and UX designers on BG:EE debated icons vs. labels for three days straight. Afterwards, the UX designer disappeared under mysterious circumstances, and the decision was made to use only icons in the user interface, with text of any kind being a last resort.

My theory: the UI and UX designers on BG:EE debated icons vs. labels hotly for three days and three nights. Afterwards, the UX designer died in a suspicious accident, and the decision was made to use only use labels as a last resort.

Am I on the verge of death? Eh, it’s probably not important.

For games where your characters have a finite amount of life, video games typically use three primary ways of displaying this information:

  • Health Bars! Either over your character or close to their portrait.
  • Numeric quantities! Same placement possibilities as health bars.
  • A color, ranging from green to red, to indicate overall damage.

In addition, some games do crazy things, like making the health bar be color coded. Or making the health bar be a pie (like in Mario 64). The really fancy shamncy ones might even hide your health bar if you’re at full health, or show both a health bar AND a text readout AT THE SAME TIME!

A pie instead of a bar? BRILLIANT!

A pie instead of a bar? BRILLIANT!

Baldur’s Gate eschews these conventions and displays NOTHING AT ALL. So you have no way of knowing if that character you’re sending in to check the room for traps will die if he steps on a pin.

I’m slightly exaggerating –  you can actually see your character’s health but pressing and holding (no toggle available) the little magnifying glass icon. Sadly, you can’t do anything else while holding this incredibly useful button down. The interface will detect a pinch gesture, zooming in or out the view into the game world. Argh!

I am reminded of Robin Williams bit about the invention of golf. Paraphrasing: "It's kind of like pool, except there's a really fucked up stick you use to play it, and you have to hit it 400 yards rather than 3 feet." Not having the "highlight" feature be something you can simply leave is kind of like that.

I am reminded of the Robin Williams bit about the invention of golf. Paraphrasing: “It’s kind of like pool, except there’s a really fucked up, curved stick you use to play it, and you have to hit the ball 400 yards rather than 3 feet.” Not having the “highlight” feature be something you can simply leave on is kind of like that.

What exactly is interactive?

On a touch based interface, interactive elements need to be obvious, because you don’t have a hover state. Otherwise, you’re going to be endlessly tapping at random until you develop RSI on your pointer finger and need to spend thousands of dollars on therapy.

In Baldur’s gate, that lovely magnifying glass icon is the only way to reveal interactive objects, and it doesn’t show level entrances/exits (I’ve read that you can see them by mouse hovering in the PC version, but haven’t confirmed this). It took me 5 minutes to find my way to the basement in the tutorial level:

IMG_0138

Where’s Waldo: Round two. I ended up walking the entire circumference of the room until I found the exit. Yes, I must be a masochist. Otherwise, I would have exited the room by simply deleting the app off of my iPad.

This issue and the previous one can be mostly fixed with one change: Make the magnifying glass icon (actually called Highlight) be a toggle. Leaving it on all the time would solve (though poorly) all of the issues related to exploration and health display except for showing zone exits.

If you wanted to actually apply some design with your UX overhaul, you could accomplish the same thing without much work. First, add health bars to your character portraits so they don’t clutter up the game world. Make tappable crates sparkle like interactive elements do in World of Warcraft and zone exits have a subtle, animated reflective effect around their frames, like doorways do in Assassin’s Creed 3. People smarter than you or me have already invented this stuff – just copy it.

More on the long death… I mean long press.

After mastering the faux-long-press — ok, mastering is a strong word, but I could at least make it work almost 50% of the time – I was confident I could muddle my way through the interface.

I noticed a question mark button on the left side of the screen and started using it judiciously. Suddenly, the jumble of icons started having names! However faint, I felt the first tremulous feelings of joy creeping into my Baldur’s Gate experience. Even better, the help menu was context sensitive, bringing me to relevant help no matter what I had selected.

So I selected my Druid character by tapping her portrait. I tapped the spell icon to pull up her spells, then launched the help. Amazingly, I could see multiple spell names in one place! As far as I know, this is the only place in the game you can see a labeled list.

Spells! Beautiful, untouchable spells! Like that girl you liked that wouldn't give you the time of day.

Hallelujah! Spells! Beautiful, labeled spells!

Being the optimistic fool that I am, I tried Baldur’s-stupid-long-press-implementation on the Entagle spell to pull up more details. Nothing happened. Assuming I simply didn’t get the timing right or finger placement correct, I tried again. And again. And again. Still nothing. Apparently, it’s not possible to get to the the detailed spell description from the help screen, which is the one place you would think it would be most useful.

All was not lost, I thought, maybe I can tap the spell icon to cast it. Still nothing. The entire help screen is completely non-interactive. Ugh. Did the people who designed this ever watch a beginner try to play?

In summary…

Nobody gives a damn. Despite its crimes against humanity, Baldur’s Gate is still in the top ten on the iPad app store a few days after launch despite its (relatively) high price tag. It has managed to maintain a respectable 4 star rating. However, looking at the most recent ten reviews at the time of this writing, a full 7 of them mention UI or usability problems as major issues.

If there's one thing a touch interface needs, it's the ability to adjust the keyboard and mouse scrolling speeds.

If there’s one thing a touch interface needs, it’s the ability to adjust the keyboard and mouse scrolling speeds.

Oh, and one last thing. That Entangle spell that I couldn’t get to the description of? I found out what it does. It makes your UI extremely laggy and unresponsive for about a minute, slows down an iPad 3rd generation to rendering about two frames per second, and as a side effect, roots both enemies and your characters in place:

I really wish this spell only turned my game into a slideshow. The trapping all my characters is an unwanted side effect.

This Entangle spell is so meta.

How to make a UIWebView with a Header like Mobile Safari

The Problem

The header in Mobile Safari does a lot of things really brilliantly: the header stays fixed at the top but you can swipe up to hide it. When you tap a link and a page starts loading, it comes down so you can see it, but if you scroll all the way to the top you can pull it back down. Instead of the scroll bars appearing over everything as in a traditional UIScrollView, the bars end one point below the header, which gives them a very neat appearance. It’s the type of thing you don’t notice as a user, but when you have to implement it at as programmer you have to think about all the thought that went into making it behave that way (and the amount of trial and error it must have taken to get it just right!).

I wanted to use this style of header, but I couldn’t find a good article, Stack Overflow answer or piece of open source code on Github to create a UIWebView with header that behaves just like Mobile Safari. After a bunch of thinking, coding, experimenting, and a pro tip from Eric Blair to look into scrollIndicatorInsets, I finally came up a solution.

Mobile Safari’s Header Behavior when pulling down into negative contentOffset.y values.

The Solution

In short: Attach the header view to your UIWebView’s scrollView, adjust UIEdgeInsets, and in the scrollViewDidScroll delegate function adjust the scrollIndicatorInsets as needed.

I wrote an open source class that does all this at  https://github.com/manesh/MMWebViewWithSmartHeader. It’s still missing a few things, like proper rotation/zooming support and the upper shadow on the scrollView, but it should be enough to get you started in the right direction. It also lets you pin an arbitrary header view at the top, just like how Mobile Safari does when it’s loading a new page, though you’ll have to write the logic for when to pin/unpin yourself!

MMSmartHeaderWebView, my open source solution, faithfully copying Mobile Safari’s behavior.

Well, that’s all for today’s post. I hope you found it useful!

Thoughts on UI Design

I discovered an old blog post of mine here and decided to repost it – grammatical errors, terrible jokes, factual inaccuracies, pointless intro and horrible sign-off intact :) .

The thing is, what I believed then is the same as what I believe now – UI Design is at the heart of everything. Almost none of the technology we get excited about is really “new”. I was a little surprised at how in the intervening two years, my thoughts on the matter haven’t changed.

Without further ado, here’s my original post:

———

The only thing worse than shoveling snow is shoveling it after cars have had a chance to drive over it, and it’s melted and frozen a few times. Which is why I got up early this morning to get that out of the way. I call it, “being an adult”.

Today’s topic is UI design and inventions of the last ten years. Coincidentally, most UI design is worse than shoveling snow.

Perhaps a primer. I’m into UI design. I think it’s the most important item that’s left “unsolved” in technology. We have enough processing power in just about any modern device to do amazing things. Your average microwave (probably) has more main memory than the computers that went to the moon. The problem is, how do you make all this great technology, all this processing power, useful to everyone? The answer lies in UI design.

I’ve been reading multiple articles on slashdot and techcrunch (my go-to sites for news I find interesting) about the “top technology inventions of the decade”. What have I found? The devices lauded from both lists are those with great UIs (which stands for User Interface, for the uninitiated. I wonder if anyone has used UI to describe UnInitiated before? bad joke).

Let’s start with the iphone, because everyone is amazed about how great and innovative its UI is, and how it was one of the greatest inventions of the decade. I don’t disagree, but keep in mind, the iphone came out in 2008. Before that, the phrase “multitouch” was practically unheard of. Except for a geek like me. I’d seen a demo of multitouch, with many of the same gestures and usability possibilities – around 2002. To me it looked rather polished. When the iphone came out, everyone else was so excited/amazed by this “new” technology.

But the technology wasn’t new. It was just the UI. According to wikipedia, the first device that supported multitouch was built in 1982. That’s 26 years from technology to popular device.

So why did it take so long?

The simplest answer is, because it cost too much. Business: Get the technology out there, get it working for someone, revise the design later. The world turns on money, and people want a working product. Building a good UI costs money, because you need good designers and a lot of testing to figure out what’s the easiest and most intuitive. In my time working on the UI for Ubequity, getting everything to just feel right is a lot of work, and it’s hard to get it just right. When you’re on a deadline, making the UI as polished as possible takes a backseat to making sure the database updates or the calculation is correct.

That’s why Apple has such a good image – because of good UI design. People may not realize it, but whenever they compliment an Apple product, it’s not because of the processor, or memory, or wireless transfer speed, or battery life. It’s because the UI just feels right. (I say this as I type from an Apple laptop which I picked over a cheaper model from last year because the keyboard feels nicer to me).

This came off as a bit of a ramble but the point I’m trying to make is this: There’s a lot of great technology, and most of it has been around for a long time. The problem is, the UI design hasn’t kept up. Those who can make good UIs will be the Apples of the future, because that is the primary thing that sets good technology apart from the merely mediocre.

mike out

The longer I live the more I see that I am never wrong about anything, and that all the pains that I have so humbly taken to verify my notions have only wasted my time.”  - George Bernard Shaw

Life – MTG Score Tracker – Development Postmortem

Every developer has a folder somewhere on their computer with a bunch of unfinished projects. If you’re like me, it’s named “code”, but a more accurate term would probably be “graveyard”.

On Saturday, April 14th, this was really bothering me. I was tossing and turning in bed, thinking about all the projects I’d started, but never finished: Massive RPGs, complicated browsers, 4X space games. As someone who’s been doing iOS development full-time for 2 years, it seemed silly that I didn’t have any apps with my name on them in the app store.

So I started thinking: What could I potentially do in a weekend? Something that was compact enough that I could finish it and polish it in a day or two?

It ended up taking a bit more than just a weekend, as development projects are wont to do. I had the idea fully formed by 3AM, and managed to submit it to the app store on 2AM on the following Saturday – taking an idea from conception to product in just under a week.

 

THE IDEA

I’m not ashamed to say most of my ideas aren’t that original. My process for app ideas so far has been as follows:

- I search the app store for something I want.

- I can’t find anything similar to what I want OR I hate the apps I do find.

- I repeat this several times, usually over a period of weeks or months.

- I start work on an app to fill the need.

Luckily, there was an app idea I had from this process. One that also met my requirement of “doable in a  weekend”:

A Magic: The Gathering (MTG) score tracker.

Magic: The Gathering is a popular trading card game (I believe the most popular one there is, but I could be wrong). The rules can get complicated, but score tracking is easy: Each player starts with 20 points of life, and zero poison counters. The first player to either be reduced to 0 life or reach 10 poison counters loses. Devices used to do this include dice, coins, token, and the classic: pen and paper.

There are just under a dozen apps that perform this function on the app store. So it’s not anything close to an original idea. However, there weren’t any apps that worked how I wanted them to. Most of the apps used some sort of custom input methods: One lets you select a number using a picker wheel, then you tap a player’s name to add/subtract. Several have arrays of buttons: +1, +5, -1, -5, etc. Most don’t have a history.

I didn’t like any of them. I ended up opening notes and manually typing in score totals whenever they changed. For me, typing was more accurate, faster, and more reliable. Also, having a history is critical to me. For instance, one problem I had was I might forget to enter a life total after a player took damage. By being able to see the whole game log, I can quickly reconstruct the series of events and see if I recorded the most recent one. I came up with an idea for a way to do this in an app, and somewhat satisfied with myself, fell asleep.

Life tracking in notes.

 

STARTING DEVELOPMENT

On Saturday, I spent some time mocking up interfaces and looking up libraries to use for the interface. I wanted the life & poison tracking to look like a Messages conversation. I also wanted to use a sliding view for navigation (similar to Facebook and Path). Eventually, I found two pieces of open source code that helped greatly: ECSlidingViewController & AcaniChat.

I also decided to focus on having a few screens in the app: The current game view, a history view, and a feedback view (which would simply have a link to a support email & the ratings page on the app store). There would also be the menu view for accessing all of these, and it would also include a “new game” function (which would load a new game into the current game view).

The First Mockup

Originally, I wasn’t going to have a menu under the right side of the screen – just a menu on the left with a few items, one of them being a game history. However, after I got it working, I found it to be a poor experience. Dragging out the menu, tapping history, then selecting an item wasn’t so bad. The problem was, the process had to be repeated to view other games in the app history, when it should have been just a slide or tap away. I moved the history to show on the right side of the screen to solve this. Another accident I ended up keeping was not removing the highlight from a history row after it had been tapped. Thus, the current game would be highlighted if the view didn’t reload. I found this to be a useful feature, for instance, if browsing the history one by one, so I wrote a few lines of code to make sure the current game’s row is always highlighted.

  

Originally, the history was going to be accessible as a menu item underneath the left side of the view, which became the top navigation view when tapped.

The final version of the history is located under the right side of the view, so it's always a single swipe away from the current game.

Also, I was originally planning to go with a full-size (44pt) status bar, but when I was laying out the interface, I tried using a half-size one (22pt) and stuck with it. I’ve seen a lot of discussion around obvious interfaces (Apple’s built in ones) versus elegant ones (Paper, Clear), and decided to go for the latter in this app. I compromise slightly by making the slide-out menus tappable and easy to tap – the tappable area is 44x44pt. I’ve found in showing the app to a few people that they don’t recognize the little icons in the corners as buttons, which may be something I’ll consider changing in an update.

The final "current game" view.

 

TRADEMARKS & COPYRIGHT, OH MY

Originally, I was going to use the white mana symbol in my app icon, and throughout the app. A huge number of MTG apps in the app store have all five of the MTG mana symbols in their app icons, so I originally assumed they must not be trademarked. On the night before I submitted, I looked it up to be sure, and discovered that the distinctive symbols actually were trademarked. Knowing this, I had to create a new icon and artwork for use throughout the app, to replace the potentially infringing material. I came up with a couple different designs that were similar in theme (8-pointed suns) but clearly distinguishable from the trademark.

Icon designs for the app that were clearly distinguishable from MTG's trademarked "White" symbol. I decided to go with the one on the far right.

 

BUT IT DOESN’T DO “X”…

By Friday night, I was determined to finish the app and submit it, even if some things weren’t perfect. For instance, you can enter player names, but the UITextField is only 22pts tall making it hard to tap. I wanted to make the tappable area a bit larger, and display the UITextView in a modal dialog for easy entry (converting the UITextField at the top to a UILabel), but decided it was “good enough” and it was better to ship it than obsess over something people might not even notice or care about (I originally wasn’t planning on making the player name customizable, but it was a huge value-add for browsing the history).

There are also a lot of things that could be better – the History view’s layout could be visually much more pleasing, wins and losses should be tracked, it should be possible to pull up old names so you don’t have to manually type the whole thing in if you have used the name before, put in notes (for instance, what type of deck you were playing with), implement a slick show/hide for the number entry exactly like messages (if you swipe down and over the bottom bar in Messages, the message entry bar & text field will begin to move down smoothly, and you can either flick it all the way down to hide or pull it back up to keep it visible), chart wins and losses, display health and poison counters as current totals as well as the history…

But screw it all, I’ll ship it now, and add more features in 2.0.

I went to my first hackathon the day after and serendipitously learned a good acronym to describe it: MVP, or Minimum Valuable Product. I think the app as it stands will be useful & enjoyable to use, if not full-featured. For 1.0, that’s good enough.

The launch image.

 

THE FUTURE

Life should be hitting the app store this weekend. It’ll be free, but if it gets a large amount of downloads, I’ll probably add IAP for optional custom skins to monetize. I have no expectations, but my main goal wasn’t to make money from this app: it was to take something from start to finish in a short amount of time, and have something out there with my name on it.

// in short

self.streetCred++;

 

Until next time, that’s all, folks!

Core Data Migration issue with invalid references (Cocoa error 1560 / 1570)

Been a long time since I’ve had something interesting to post here. First, a bit of background:

I’ve been working on an app at my day job that was created a long, long time ago (in a galaxy far, far away). It worked well enough at first, but a bunch of new features were required as time went on, and it fell to me to add them. As part of this process, significant additions were needed to the database, so I had to do the whole migration thing: setting up a new data model, making sure to load the database with migration enabled, adding the model mapping as well as setting up a custom mapping.

In my testing, it worked, however,  when I handed it off to testers they kept having issues. The error log looked something like this (except duplicated many times):

Error adding persistent store

Error Domain=NSCocoaErrorDomain Code=w “The operation couldn’t be completed. (Cocoa error 1560.)” UserInfo=0x7cf8d70 {NSDetailedErrors=(

“Error Domain=NSCocoaErrorDomain Code=1570 \”The operation couldn\U2019t be completed. (Cocoa error 1570.)\” UserInfo=0x7cd5080 {NSValidationErrorObject=<NSManagedObject: 0xb537d40> (entity: Answer; id: 0xb53c0f0 <x-coredata://F0E5C13E-9F62-4005-98FD-576804C21DFF/Answer/p5> ; data: <fault>), NSValidationErrorKey=inspection, NSLocalizedDescription=The operation couldn\U2019t be completed. (Cocoa error 1570.)}”,

“Error Domain=NSCocoaErrorDomain Code=1570 \”The operation couldn\U2019t be completed. (Cocoa error 1570.)\” UserInfo=0x7ce9f90 {NSValidationErrorObject=<NSManagedObject: 0xb537860> (entity: Answer; id: 0xb53c970 <x-coredata://F0E5C13E-9F62-4005-98FD-576804C21DFF/Answer/p22> ; data: <fault>), NSValidationErrorKey=inspection, NSLocalizedDescription=The operation couldn\U2019t be completed. (Cocoa error 1570.)}”,

With a lot of Googling and testing until I found exactly what how to reproduce the error, I finally figured out what was happening:

  1. In Core Data, the managed object “Answer” had a required one-way relationship with “Inspection”.
  2. Inspections could be deleted from the app. Since they did not have an inverse relationship, deleting them did not delete the Answer objects.
  3. Core Data apparently does not immediately re-validate after deletion (news to me), so the database was left in an invalid state afterwards, with the Answer objects having a nil required relationship. This is clearly a bug, but since it never had any impact on the user experience, it wasn’t caught originally.
  4. After migrating objects and relationships, validation is automatically performed (migration is a 3-step process: copy managed objects, re-create relationships, validate). Because the data that did not validate, the migration would fail.

Once I figured out what was happening, I thought of a few potential ways of fixing it:

  1. Add custom migration logic so that when an Answer object is migrated, if the relationships are invalid, it is simply deleted from the database.
  2. Load the old data model first, load the data, fix it, then perform migration.
  3. Change the relationships in the new model to no longer be required.

I ended up using #3 after failing to figure out how to make #1 to work in a short period of time (deadlines, deadlines). Next release though, the plan is to write a run-once routine to clean up all the unneeded rows, in addition to making sure everything is deleted properly in the first place.

TL;DR: Core Data doesn’t immediately validate managed objects after a deletion, but does after migration, which will cause “NSValidationErrors”.

What I’ve Been Up To

Joined a support group

I started attending NSCoderNightDC. Suffice to say, it’s one of my favorite activities of the week. I’ve met some really cool people there. This post was inspired by Luis de la Rosa, a fellow NSCoder, who challenged me to a blog writing contest. Apparently, the loser has to buy the winner a pastry. If that’s not motivation, I don’t know what is!

Finished an app

HealthyWomen Passport to Good Health (and a Plus version), which I was the sole developer on, was published to the app store. I had a good amount of design support from the extremely talented Ian Betts (he can make buttons sing). I might write a few posts about the process at some point – there’s a lot of things I could have done better when looking at it with hindsight. The app was published for HealthyWomen (a non profit organization) on behalf of Booz Allen Hamilton, the company I currently work for.

Speaking of which – I’m now working on an iPad app at my day job. For the first time in my career I have a chance to interact with other developers on a daily basis. Even more interestingly, they all have extremely strong .NET backgrounds as that’s what their current system is built on, and I’ve had a chance to learn about C# as I build an iPad version of it. Occasionally, I get a chance to teach them a few things about Xcode & Objective-C – it’s apparently the best way to learn!

Games will be made

I’ve started learning Cocos2d and building my first game. I also somehow convinced the incredibly talented Mike Ash (who I also met at NSCoderNightDC) that we should make a strategy game for the iPad. Well I can’t guarantee either will be a success (or even be finished), I’ve already learned a lot of things along the way.

WWDC

I lucked out and got a ticket to WWDC! Both excited and nervous to be going for the first time. Maybe I’ll even be able to catch a glimpse of “His Steveness”!

Well, that’s all for now. Next time, I’ll be back to trying to sound like I know what I’m talking about. Ciao!

Non-Scrolling UITextView in UITableViewCell – moving the tableView to show the cursor

Basic idea: Put a non-scrolling UITextView in a UITableViewCell. Resize the UITableViewCell whenever the UITextView’s text causes a line break to occur (did this using the -[NSString sizeWithfont] function).

Worked great, the problem was when the textview became greater than the size of the UITableView with a keyboard on screen, weird behavior would occur, like scrolling to the top even if the user placed the cursor at the bottom with a touch, meaning the user couldn’t see where he/she was typing.

So I wrote this hack. It could definitely use some refactoring but it works for me. How it works: Find the range, trim the string based on the range, find the size of the string in the textView with sizeWithFont. Now we have a height value we need to scroll down to within the cell. Then, find where the cell is located within the tableView, and add the distance we need to scroll down in the cell to get to the text view, and use -[UITableView scrollRectToVisible:animated] to move the tableView there.

It still animates a little strangely when first selecting the tableView but that’s something to figure out another time…

- (void)textViewDidChangeSelection:(UITextView *)aTextView {
// if there is a selection cursor…
if(textView.selectedRange.location != NSNotFound) {

NSLog(@”selectedRange: %d %d”, textView.selectedRange.location, textView.selectedRange.length);

// get the text so far
NSRange range;
range.location = textView.selectedRange.location;
range.length = [textView.text length] – range.location;
NSLog(@”range is: %d %d”, range.location, range.length);

// if it’s not the last character
if(range.length != 0) {
// get rid of all characters past the selection point
NSString *string = [textView.text stringByReplacingCharactersInRange:range withString:@""];
NSLog(@”string has been trimmed: %@”, string);

// figure out the size that this textView would be if it only had this text
CGSize size = [string sizeWithFont:textView.font constrainedToSize:CGSizeMake(289.f, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap];
NSLog(@”height is: %f”, size.height);

// now we need coords in out tableview to scroll to
UITableView *tView = (UITableView *)[self superview];
CGRect cellRect = [tView rectForRowAtIndexPath:[tView indexPathForCell:self]];
NSLog(@”cellRect origin.y is: %f”, cellRect.origin.y);

// add the height to the origin of the existing rect, and scroll to it
CGRect finalRect = CGRectMake(10.f, cellRect.origin.y + size.height, 300.f, 100.f);
[tView scrollRectToVisible:finalRect animated:YES];
}

}
}

Update May 12, 2011:

Here is the code I use to resize the text view when the text becomes larger or smaller. It may be even more unreliable than the above hack (note the use of a fixed width), use at your own risk.

- (void)textViewDidChange:(UITextView *)textView {

// find the height of the text & text view
CGSize size = [textView.text sizeWithFont:textView.font constrainedToSize:CGSizeMake(289.f, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap];
CGRect rect = CGRectMake(10.f, 24.f, 305.f, MAX(size.height, 16.f)+ 24.f );
textView.frame = rect;

// let the table know a row height is going to change
UITableView *tView = (UITableView *) [self superview];
if(tView != nil) {
[tView beginUpdates];
}

// change the height of the row
self.rowHeight = MAX(size.height, 16.f) + 44.f;

// commit the row height change
if(tView != nil) {
[tView endUpdates];
}

}

 

 

Class Category to prevent a UISearchDisplayController from hiding the navigation bar

Annoyingly, the “right” method of calling setNavigationBarHidden:animated when the search begins will hide the bar, then show it. This is the only solution that isn’t ugly.

Original Source: Stack Overflow

Code below, modified so that it actually works (The super call in the linked question causes a crash so I took it out, and I used an inline Class Cateogry, DoNotHideBar, to avoid making a new file just to overwrite this one function):

@implementation UISearchDisplayController (DoNotHideBar)
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
    if(self.active == visible) return;
    [self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
    [self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
    if (visible) {
        [self.searchBar becomeFirstResponder];
    } else {
        [self.searchBar resignFirstResponder];
    }
}
@end

Fun Fact about Viagra

Building an iPhone app that utilizes data from the FDA’s downloadable drug database.

When looking through the data, I noticed that the company code for Pfizer, maker of Viagra, is 0069.

The more you know…