ChaniBlog











{September 7, 2014}   Blip.tv screencasts moved

Blip.tv has decided to narrow its focus, and isn’t interested in hosting my screencasts any more. I’ve moved the two 4.6 screencasts to youtube: Activities in KDE Plasma Desktop 4.6 and Activities in action. If you’d like any of the older ones (Activity Sessions, Activities in KDE SC 4.5beta1, Plasma Activities in KDE SC 4.4) to go up on youtube too, just ask. :)



{August 29, 2014}   On boundaries

So… Julie Pagano blogged about boundaries and consent. You should read it.

…go on, I’ll still be here when you get back. :)

Anyways, it’s a good post, but I felt like the first point (Entitlement) could be elaborated on. It’s something I misunderstood at a fundamental level for a long time. I honestly thought the rule was “you can have boundaries, if you have a good reason for them.” Somehow I grew up thinking it was ok for other people to demand a reason for my “no” (in any situation other than sex) and judge whether it was a valid reason. And, of course, that I could expect justification from other people.

I like making people happy. I hate upsetting people. So I was totally happy to give people what they wanted… after I understood why they wanted it. After all, being confused really sucks. I hate feeling confused, I hate uncertainty. I hate wondering whether I did something wrong or if the other person was just having a bad day or whatever. And being an aspie, I’m confused a lot. :)

I think I did have a bit of a sense that I wasn’t handling things quite right. But having no idea what the Right Way was, I didn’t know what else to do. Lots of people have conflicting opinions on social norms, and some of them have their own agenda colouring their advice too, so I don’t know who to trust. So, I just keep listening, until someday something clicks and another bit of social behaviour makes sense, and feels right. (It helps that I’m following some prominent feminists on twitter lately. They’ve had to think about and experience this shit a lot, so their opinions tend to be quite sensible.)

I’m not even sure when I figured this one out. It was probably a gradual thing. But I do remember how good it felt to realize that I didn’t have to justify my boundaries. That I was allowed to just say no, or ask someone to stop doing something, or block someone, and I didn’t have to figure out a bullet-proof justification first. That was a huge weight off my shoulders, and suddenly I felt more confident and.. I dunno… adult.

It still feels bad when someone has boundaries where I’d prefer they didn’t, but, instead of trying to understand what’s going on on their side, I have a sort of deeper understanding: I understand that they’re allowed to do that, and that it’s important to their sanity and freedom as an adult to have that right. And that’s more important than my discomfort, even if the discomfort does suck. Accepting the discomfort makes it much less likely to turn into a panic attack, too ;)

I’m kinda scared to hit the publish button now. This is such a murky confusing subject, and I might still have said something incredibly stupid. I might still be wrong about a lot of this stuff. Or someone might try to tell me I’m wrong when I’m right. Either way they might be mean about it. The internet is a scary place. But, I hope this post has given some people food for thought. This stuff is worth thinking about, over and over again, until we do get it right.



{May 29, 2014}   Spoons.

I was going to title this “burnout sucks” or something, but then a friend sent me to spoon theory. Go on, read it, I’ll still be here. :)

See, I’ve had a migraine/tension headache since february. It’s the end of may, now. Yes, that’s not normal. Yes, I’ve seen doctors, lots of them. Yes, they’ve tried whatever you’re about to suggest. (Except hypnotherapy and trigger point therapy, those are next week).

At first, I thought it was just another persistent headache. it was mid-march, iirc, when I finally stopped trying to work despite the pain. Stress was definitely a trigger – we had an awesome android contract, with more android to come, and I was the “lead” android developer (the other developers being more interested in iOS). I wanted to impress everyone and was pushing myself too far. Some internal matters were stressing me out too, but that’s none of your business. :)

The first 6 weeks or so were pretty awful. Pain, lots of pain. Not severe pain, just enough to distract me, to discourage me from thinking or doing anything, to make me thoroughly miserable. And I desperately wanted to do.. well, things in general. The idea of lying in bed and being unproductive was extremely discomforting. Does that make me a workaholic? It’s not like I was capable of much work, but it was very hard to accept that I needed to rest. every time I thought I was taking it easy, another layer unraveled and I learned that I was still being too hard on myself.

Then my neck went fucking crazy and I was stuck in bed for two days (except for some excruciatingly painful walks to the bathroom). You have no idea how much neck muscle is involved in just holding your head up on your shoulders. That neck pain’s been an issue ever since, although not bad enough to prevent me from standing up at all (thank god).

Since then… well, the pain (head and neck) died down, slowly. It flares up again, if I push too hard (like, two shopping trips in one day, or more than an hour talking to someone) or if it just fucking feels like it (aaaaargh!!). But the headache came with a side effect. Noise sensitivity. On a good day, I have to hide in the bedroom when Pete does the dishes. On a bad day, I can’t stand to have him in the house at all. :(

So that’s two (three?) problems that modern science doesn’t understand and can’t solve. There’s more, too, but nevermind that. Problem #4 is that I am burnt the fuck out. I’m not sure if I didn’t notice it or just refused to believe it… but I’ve had a lot of time to think lately, and eventually I had to acknowledge that I was more enthusiastic about cleaning the bathroom than writing code, even for my own personal app that would be really awesome to have working. :( All this lying about, attempting to rest, has helped a bit, though; I can at least see that I’m burnt out, now, and after resting enough I have the occasional burst of true enthusiasm (which I can’t actually act on, or I’d trigger the headaches again…)

The days have gone by fairly fast, and given the situation, I’m doing fairly well. I still have days where I’m so frustrated I just want to curl up and cry. I have days where I wish the migraine was a physical thing so I could beat the fucking shit out of it. I have days where I’m terrified I might never be well enough to work again. I miss parties so much, so very very much. But I also have days where I feel content to just enjoy the sunshine, or read, or days when I’m well enough to play video games. I seem to have switched back to the introverted personality I had as a kid, which makes it much easier to spend all day lost in a book. I’ve started to draw again, and on my worst days (when even reading hurts), I’ve rediscovered the joy of daydreaming.

To be honest, it’s very confusing and surreal. Here I am, supposedly grown up, and illness has forced me back into the habits of childhood. It took a long time to stop feeling guilty whenever I felt a flash of enjoyment. I still have days where I somehow forget that I’m not well, and feel confused and hurt when I’m not able to handle a full day of chores or errands. Some days I wish I could just be normal; others I’m actually scared of getting better, scared that I won’t be able to cope with “normal” life even when the physical pain is gone (I’m still burnt out, after all, and that’s not the only issue to deal with). Most days, though, I manage to forget about “normal” life, avoid thinking about fun things I can’t do, and enjoy the little things that I can do. :)

Hopefully one day I’ll be better, and I can hack again and make awesome things. Until then, well, I’ll just do what I can, and try to remember to take care of myself.

edit: I forgot to mention, I’m really grateful for the medical system and EI here in Canada. It’s not perfect, but EI is paying my (non-medical) bills for now, and none of the doctors have been skeptical of my mostly-invisible pain. It means a lot to know that the country I pay taxes to is willing to take care of me in return. :) And Steamclock has been very understanding, and is still taking care of my health insurance, too. :)

P.S. If you’re looking for canadian health insurance, don’t pick Sun Life, they’re very restrictive about what they cover. :P



I’ve been doing a lot of Android dev lately. Which of course means even more swearing than usual (yep, that is possible). It’s actually been fun, in a bizarre why-am-I-enjoying-this-torture kind of way, but there’s been a steady stream of WTFs along the way, and a surprising number of them involve EditText.

god damn fucking edittext. It’s just a little widget to get some text from the user. how hard could that be, right? :P

I had problems right off the bat with my personal app I started over the holidays. That one was simple – I used the standard fragments+viewpager template, threw an edittext on my layout, and tried to get me some text. Nope. By default, EditText is multiline, so you have an enter key that inserts a newline instead of a submit button. I was okay with multiline in the sense that it should grow and wrap text if I type a lot, but I didn’t want actual newlines, I wanted a ‘done’ button. I could have added a separate button to my UI, but that’s no fun :P so I fought with getting that button to show on the keyboard. Turns out, you need not only android:imeOptions="actionDone" (or submit or next or whatever), but also a sensible value for android:inputType (which took ages of trial and error to figure out – autocorrect vs autocomplete was not clearly explained at all) which in my case was android:inputType="text|textCapSentences|textAutoCorrect" (I c&p that as the default for all my edittexts now).

Then there are the weird issues with focus when you leave fragments or click another edittext. mostly they just cause warnings, but on kitkat some of those warnings turn into crashes.

Oh, and another weird thing – clicking ‘done’ or ‘submit’ or whatever does not automagically dismiss the keyboard. nor does leaving the fragment (and the keyboard does not like it when it’s still open and its edittext has vanished). The code to manually hide it is so ugly that I was sure it must be a dangerous hack, and was reluctant to use it, but it appears to be the only way.

    static public void hideKeyboard(View focusView) {
        InputMethodManager imm = (InputMethodManager) focusView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(focusView.getWindowToken(), 0);
    }
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        //Log.e(TAG, String.format("onEditorAction %d", actionId));
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            setAndSaveText(v.getText().toString());
            Helpers.hideKeyboard(v);
            return true;
        }
        return false;
    }
//I have to manually call this whenever I do a fragment transaction.
    private void onFragmentChange() {
        View focus = getCurrentFocus();
        if (focus != null) {
            //Log.e(TAG, "focus: " + focus.toString());
            //keyboard should go away when leaving a fragment. how is this not standard?!
            Helpers.hideKeyboard(focus);

            //fix focusout bug on api 15
            //notes: dispatchWindowFocusChanged does nothing.
            //clearFocus works on api 15, but also calls onfocusin,
            // and gives worrying error messages on kitkat (nexus 5).
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                focus.clearFocus();
            }
        }
    }

Okay, that’s it for the problems encountered with a simple, common view. But then I started a more interesting project, where I needed to dynamically set up layouts at runtime. Yep, some of those layouts had edittexts in them, and that gets interesting. In a throw-your-computer-out-the-window kind of way. :P

The natural approach to a dynamic UI would be a ListView, right? It would just make sense, right? Wrong :P ListView and EditText do not get along. Period. Nothing’s stopping you from trying to put an EditText in a ListView, but if you do, spooky shit will start happening. Your keyboard will go crazy. Text will fail to appear, or focus will jump to the wrong place, or the cursor will show up in the wrong part of the screen… and on kitkat, it’ll just outright crash sometimes. After much googling and some rather depressing stackoverflow comments, I decided it was easier to just use a LinearLayout in a ScrollView. (luckily I won’t have enough rows for performance to matter.)

Everything seemed rosy again for a while, but here and there I was having issues with the text blanking out, or getting the text of a different EditText. Then I added a subscreen, and on returning to the screen with edittexts, poof, loads of text was disappearing. Oh, and radiobuttons were resetting too. Eventually I tracked it down to a really insidious side-effect of android’s helpful automatic view save/restore code. It was assuming that every view in the fragment has a completely unique ID, and since I’d instantiated multiple rows off the same layout, this was not the case.

I knew ListView had to have been preventing this somehow, so I dug in (thank god most of android is still open-source) and found what it had done: blocking dispatchSaveInstanceState and dispatchRestoreInstanceState. I made my own subclass of LinearLayout that did the same blocking, and all my widgets were happy again. :)

public class FormContainer extends LinearLayout {
    public FormContainer(Context context) {
        super(context);
    }
    public FormContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public FormContainer(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    //prevent save/restore of our children
    @Override
    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
        super.dispatchFreezeSelfOnly(container);
    }
    @Override
    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
        super.dispatchThawSelfOnly(container);
    }
}

Well, there are still some warnings when I jump directly from one edittext to another. But I think this is as good as it gets :P



{January 9, 2014}   Why am I not blogging?

Goddamnit, I haven’t blogged in forever. I at least started a post on robotsconf, but never finished it. I’m damn well going to blog about *something* today, so, let’s talk about possible explanations for my not blogging.

This is going to be a rambling stream-of-consciousness post with no editing except to combat autocorrect. Because one of the things that makes it hard to blog is worrying about whether I could have phrased it better. The internet can be pretty mean, and if one little sentence is badly phrased then someone’s going to jump on it. :/

Which brings me to another issue: my blog is adrift on the internet at large, instead of being part of a community. When it was a part of planetkde, and I was contributing steadily, I always knew what I wanted to talk about and who was going to read it. Even when I didn’t have some cool feature to blog about, I knew my audience. I had a feel for how many off topic posts I should write to let people know about my hobbies without boring them too much.

Now, my hobbies are in chaos – I can’t seem to settle on one thing for more than a couple of sessions – my work isn’t something I can blog about much (and NIR would most people care) and I have no fucking clue who’s reading this.

I know that I’ve picked up some followers of my food posts (sorry, no time for that lately, Pete’s doing most of the cooking), I know some tiny subset of kde people still follow my blog, and I know some people read it via twitter now that I’m auto-tweeting my posts and actually using twitter. (Actually that last one scares me a bit, you never know who’s going to end up seeing it there…)

Twitter might be part of the problem too… The free time I do have is easily sucked up by reddit and twitter. And I don’t feel like twitter is a choice, because I’d miss out on stuff in various tech circles if I didn’t check it at least every couple of days. It keeps me feeling connected in these not-quite-communities around js, Vancouver tech, etc.

But, yeah, time is an issue. I started this post on the bus, and now I’m writing during lunch while the rest of the company chats. After work and dinner, I generally don’t want to do anything hard, and blogging is hard. It takes a good 2-4 hour block for me to do a good post, iirc, and if I’m interrupted I tend to lose interest. I have that time on the weekend but I have a million other hobbies and chores and social events competing for my attention then (and if it’s work-related I can take some work time but there aren’t many of those). Plus it’s hard to convince myself the post is worth writing if I don’t know who’s reading it.

Another thing that bugs me is this WordPress app.  For the most part it’s a good app, but it has a fatal flaw: it is way too easy to publish by accident. That makes me reluctant to use it the more complex my topic is. And with the small screen it’s hard to review a post – I don’t seem to have a preview at all here – so I always want to finish editing on a desktop and publish from there.

Oh well. This time I’m just going to hit send and damn the consequences :p



I’ve noticed a pattern at conferences and meetups lately. Some guy comes up to me, and the first words out of his mouth are something like “it’s so nice to see girls in programming” or “so how can we get more women in tech?” or something. It seems quite well-intentioned – I imagine he thinks it’s an easy way to break the ice, or wants to communicate that he’s not sexist, or at worst is trying to score brownie points – but it’s making me uncomfortable. It took me a while to figure out what I was feeling – the last couple of times I just sorta awkwardly ran away – so now that I’ve figured it out, I’m blogging it.

I do not like being reminded of my gender at tech events. Especially with the recent drama I’ve been seeing on twitter. I’d much rather forget that I’m different, and talk to you about how awesome node is, or bitch about android and ios, or hear about some cool project you’re working on. Please, just use the same damn ice-breakers you’d use if I was a guy.

Besides, I do not get magical feminist superpowers from my ovaries: I’m just as lost as most guys when it comes to all the women-in-tech issues (except t-shirts. I can go on about that one for ages). That’s part of the reason I don’t want to be asked about it, I suppose; thinking about it makes me feel lost and helpless and confused. And remembering that I’m a girl makes me feel a bit more self-conscious and awkward.

I might wander into conversations about it from time to time – more likely after several drinks – but please, don’t make it the first thing you say to me.



{November 20, 2013}   Accessibility surprises

So CascadiaJS was last week, and it was awesome. I did have one issue at the start, though, which surprised me enough to blog about.

First off, the issue was resolved quite well. I’m not writing this post to complain, but to educate. I might have been too shy to bring it up, but at the start of the conference they told us who to talk to if we had any problems, even ones that seem silly. :) I’m really glad of that.

So, the issue: for the first time, I had need of the accessible bathroom. But it was locked. When I first discovered this, the staff member with the keys happened to be nearby. After explaining why I needed it, he unlocked it, but insisted on locking it again afterwards so that nobody made it messy.

Two issues here: first, having to ask made me feel really bad. I look young and healthy, but I’m not. So I end up explaining my personal health situation to a stranger to beg permission to empty my bladder. It reminded me of being in grade school, having to put my hand up and ask instead of just quietly slipping out. I wasn’t looking forward to having to ask him again – even skipping the explanation, it still meant finding him, and interrupting whatever he was doing. And doing so again every time I needed to pee (which was about once an hour). And since I feel bad about imposing on him (and humiliated too), I felt pressured to keep my bathroom visits to the minimum too.

I now have a lot more understanding of how disabled people can seem like cranky assholes sometimes. If I stopped caring about the feelings of the guy with the keys, life would be much simpler.

And then I started worrying, what if I couldn’t find him when I did need the bathroom? Which brings us to issue two: the very next time I needed it, he wasn’t there. Some nice lady helped me down to the regular bathroom then – I’d delayed so long I couldn’t wait much longer. But after lunch, he was still gone. So that’s when I went to the awesome Angelina and got the problem fixed. Bathroom unlocked for the rest of the conference, apart from a few times when the damn door re-locked itself. :)

Oh, and nobody made a mess of the bathroom anyways. Yay for responsible adults!

What I learned from this is, accessibility isn’t necessarily intuitive. I could have just as easily been the one with the keys in this situation. He made a fairly reasonable assumption (that a guaranteed-clean bathroom was better than an unlocked bathroom) that just happened to be wrong. Now I’m wondering: what wrong assumptions about accessibility do we have in our code? (Assuming there is any accessibility in the first place :P ) Or in our other attempts to be helpful in general?

It can be hard to explain when something intended to be helpful is actually hurtful, or even to understand what happened. I just hope that if I end up on the other end, the person has the nerve to speak up and I have the patience to listen.



{October 6, 2013}   How to Not be a Rockstar

Lately I’ve been keeping up with twitter, and retweeting the best of what I see. And there’s a trend in that recently: articles encouraging humility. I like this, and I feel like saying a few words myself.

Most recently, @shanley wrote (or.. crowdsourced?) an article on how the “10x engineer” is a myth, and why it’s bad. Unfortunately it just sort of trails off at the end, and I’m left a bit confused, so I’ll try to sum it up: Long ago someone did a crappy study with way too few participants, made wild claims, and then it snowballed into this myth that encourages harmful behaviour like hero-worship, overworking, depression, etc.

Been there, done that, got the t-shirt (and health issues nobody my age ought to have). And yet, it’s such a tempting trap that I keep having to drag myself away from it again. I mean, who doesn’t want to be a rockstar? Who doesn’t want to be the bestest programmer in the world, and have everyone think they’re awesome? My brain is good at avoiding substance addictions, but has a blind spot when it comes to people’s praise and approval. Besides, there’s so much in this world that I want to do, it’s hard to stop and rest when I need to the most.

Another post I retweeted was Presentation Skills Considered Harmful. It’s a very well-written post on how to reduce stage fright and be a better presenter at the same time – not “better” in the rockstar sense, but in the sense of actually being more useful to your audience. Last time I submitted a talk proposal, I had this nagging “I’m doing it wrong” feeling, and I think this post explains a lot of it – I was focused on how I could get my proposal accepted, how to make it sell and make me look like the sort of presenter everyone wants at their conference – not on how the talk could be useful to the audience. I mean, that was in there somewhere too, but it wasn’t the priority. In truth, even while writing it I didn’t really believe it was a useful talk. I just missed talking, and have yet to gain enough experience with javascript to have anything useful to say about it. :( Still, what I liked most about the article was that it gives me clear guidelines to follow when, one day, I do have something to say again. :)

Now, I find myself wondering: why is this rockstar thing so tempting? Why do I feel compelled to judge programmers, and persecute myself if I don’t appear to be the best? Why are people so eager to put someone on a pedestal and start a cult of personality? A part of my mind says, this is obvious, humans have always been that way. But I’ve found that questioning those “obvious” things can lead to interesting discoveries.

I can’t speak for other people, but for me…. it usually boils down to fear. Silly, irrational fears, which are the hardest to defeat. I fear that if I’m not the best programmer, I must be the worst programmer and I’ll end up with no job (despite having never been unemployed except by choice). I fear that if I’m not giving talks about awesome stuff, nobody will be interested in talking to me (despite all the good conversation and friends I made at WWDC, where I doubt any programmer knew less about apple tech than me). I fear that any imperfection in me could be used against my whole gender, even though the communities I hang out in wouldn’t put up with such behaviour, and the best thing I can do for other female geeks is to be myself as loud as I dare. :)

The worst part is, when I try to break away from this, I’m often overwhelmed by the fear that I somehow need these silly fears. They lie to me, and tell me that without them I’m nothing, that I’ll just lie on the couch and do nothing all day, and never accomplish anything. Yet when I’ve succeeded at putting aside those fears for a while, the opposite is true: on average, I get more motivation and energy, and accomplish more, and feel better about myself in general. Sure, sometimes I need a day or two of doing fuck-all first because I’m burnt out, but if I rest without beating myself up about it, I can’t seem to help doing something productive soon afterwards. And it’s a lot more fun when I wholeheartedly want to do it. :)

So, if you feel like your ego is hurting you… try putting it aside for a week or two. Focus on how you can help other people in your community, or at work. Try doing what’s right, even if you’re scared of getting punished for it. :) And put your health first, because you can’t help yourself or others if you work yourself to death. :P

Oh, and there’s another trap to avoid here: competitive humility isn’t real humility. If you’re putting down people for following their ego, you’re doing it wrong. And if you get angry at yourself for having an ego, you’re doing it wrong. I still want to be the bestest programmer ever. I still want oodles of money. There’s nothing intrinsically wrong with having such desires. I’m just taking them out of the driver’s seat for a while. Desires have a lot in common with two-year-olds; giving them what they want isn’t the best way to handle them, but beating them up isn’t right either. :)

Now that I think about it, fear and anger can be like two-year-olds too. Resist them directly, and they throw a wild tantrum and try their best to make you feel miserable. But give them some space and understanding, and hear them out, and they just might agree to try another way (forgive me if the metaphor is stretched; I don’t have much experience with actual two-year-olds).

Anyways, that’s enough for tonight. Maybe another time I’ll have a go at the hero-worship issue (note to self: The Speaker-vs-Audience Dichotomy is relevant reading). For now, I’ll leave you with an article that convinced me accepting tips is suboptimal, and a quote that changed how I think:

“Confidence doesn’t come from knowing you’re right – it comes from being okay with failing.” — Design is a Job



I’ve been meaning to blog about this for ages, but I seem to have writers’ block. Time to break through it!

Going from desktop kde/qt programming to mobile and web development has been quite a change. Some of the lessons I’ve learned along the way, I wish I could have read about instead of walking into. So, I’m writing about them now to save the next person from that. :)

Let’s start with node.js. I love node.js, it’s a lot of fun to work with. A shame there’s always web browsers at the other end. ;P But, node is a place where you are guaranteed to run into one of javascript’s biggest annoyances:

Callback hell

Now, for KDE programmers, callbacks might not sound so bad. Signals and slots are technically callbacks, right? And they’re easy and fun to work with. But when you strip away all that nice abstraction, you get a lot of ugliness. Ugliness like this:

doAsyncThingOne(data, function(error, result) {
    if (error) {
        ohshit();
    } else {
        doAsyncThingTwo(data, function(error, result) {
        if (error) {
            ohshit();
        } else {
            doAsyncThingThree(data, function(error, result) {
                if (error) {
                    ohshit();

…and so on. (sorry about the ugliness of the code formatting, that’s what you get on a free wordpress account.)

And that’s assuming that all your async methods use the “data, callback” pattern. it’s a popular one, but there’s another popular pattern, “data, successCallback, errorCallback” – and sometimes “data, {success:callback, error:callback}”. And then there’s the question of what pattern they expect for those callbacks you’re passing in – is it “error, results”? “results, error”? Something Completely Different?

It can get to be quite a headache quite quickly when the libraries you’re working with don’t all use the same pattern, and you always have to remember which one expects which. and there’s no compiler to warn you, either – you just get things breaking horribly or, just as often, silently dropping bits on the floor.

Cleaning it up

Fortunately the majority of libraries I’ve worked with follow the pattern in my example – including async, a library purely for reducing the pain of callback hell. Async can get that awful example down to something more manageable:

async.waterfall([
    function thingOne(next) {
        doAsyncThingOne(data, next);
    },
    doAsyncThingTwo,
    function thingThree(dataFromTwo, next) {
        doAsyncThingThree(dataFromTwo, function (error, result) {
            if (result.isCool()) {
                next(null, result);
            } else {
                next("not cool!");
            }
        });
    },
], function finalize(error, dataFromThree) {
    if (error) {
        ohshit();
    } else {
        yay(dataFromThree);
    }
});

note that since thingTwo fit async's callback expectations perfectly, we didn't even have to wrap it. :)

However, this is still pretty inflexible – what if a particular result from thingOne means that you can skip things 2 and 3 but still need 5? I've heard that Promises are more flexible in this regard, and I plan to try them out sooner or later, but I'm not sure what to do about all the libraries that don't offer a promises api. We shall see.

The ‘dummies’ part

Now, I actually got way off topic there. There’s a different problem with callbacks that inspired this blog post. I felt really goddamn stupid when I noticed I’d done it, but then I realised… everyone else working on the project had also done it somewhere.

See… the thing about callbacks, is that when you take one, you're promising to call it once, and exactly once. Not twice, not zero (excepting that thou then proceed to one ;). What we had was some callbacks that might never be called, and some that were always called twice. Or more.

Oops.

So, yeah, don't do that. It’s bad.

And… that’s it, really. I keep feeling like I should have more to say about it (One shall be the number of the counting, and the number of the counting shall be one?) but it’s just a matter of checking your code. And hopefully keeping the methods simple enough that checking the callback call doesn’t require a state diagram. :)

If you want more information, just google “callback hell”. There are plenty of other blogs about it. :) (ooh, Elm sounds interesting…)



{August 30, 2013}   UIWebView css theming

For one of our apps at SteamClock, We’re switching from a dark to a light theme for iOS 7. We’re still keeping the dark theme for iOS 6, though. This has been a bit of a pain, and today I had the “fun” of figuring out how to theme our about page, written in html. :P It took about three stackoverflow answers and a blog post for me to piece together working code, so I’m adding Yet Another blog with a solution that’s more robust (so long as your theme doesn’t change while you’re displaying it).

The gist of it is, we use external css files (something the internet was unclear on too) and then edit the html string so that it loads the correct css file for the theme.

Here’s the line of html that loads the css:

   <link rel='stylesheet' href='about-THEME.css' />

Note the lack of a leading slash in the href. It broke when I added one. Oh, and of course I’m confident that ‘THEME’ will never appear elsewhere in my html.

Now, the ios code…

First, we load the html from our resource:

        NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"about" ofType:@"html"];
        NSData *htmlData = [NSData dataWithContentsOfFile:htmlPath];
        NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];

Pretty straightforward.

Then, we swap out the ‘THEME’ placeholder for the right name:

        NSString *themeName = IS_IOS7 ? @"light" : @"dark";
        htmlString = [htmlString stringByReplacingOccurrencesOfString:@"THEME" withString: themeName];

That IS_IOS7 macro boils down to:
([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)

Now we need a base url so that it looks for the css file in the right place:

        NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];

Finally, we load the page:

        [self.webView loadHTMLString:htmlString baseURL:baseURL];

And that’s it! (well… almost. you may want to set the backgroundColor of the webView to match your css background, so that it looks nice while scrolling and such.)

Now our about page automagically fits the theme, and as an added benefit, all our translations share the same css instead of having it c&p’d into the html files. :)



et cetera
Follow

Get every new post delivered to your Inbox.

Join 361 other followers