This week, I had the opportunity to attend Web Summit – a three day tech conference that has absolutely exploded the last couple of years. Going from 500 attendees in 2010 to over 20 000 this year, it has become one of the biggest tech events in the world.

Booking the tickets just shortly after finishing 6 months worth of traveling, I was quite a bit low on cash and opted to stay in a hostel dorm. This turned out to be a good decision since Dublin hotel rates went on a craze as the event drew near. To my surprise and delight, the hostel was packed with startups and students attending the conference. Just in my dorm were a bunch of New York kids who made a messaging app and a Singaporean girl doing an internship for a startup in Stockholm.

Hostel party crew

Already the night before the actual conference, you could get a sense of how huge this thing was. The night began with a pub crawl divided into more than 100 different groups and ended up in a busy bar area where entire city blocks were shut off just for Web Summit attendees. This kept on going all week with ~15 dedicated bars each night + a number of invite-only parties.

The conference itself covered two big venues divided into different themed areas such as "builder", "marketing", "enterprise" and "machine". They all had their own speakers stages and exhibition areas where startups in various phases tried getting investors attention. Besides exhibitions and presentations, there were also round table discussions, workshops and pitch competitions among other things. Each day, there were hundreds of speakers and thousands of startups exhibiting and it soon became almost overwhelming. Planning was out of the question and I ended up just going with the flow.

Friends from Nuday Games

Since this was an event tailored mostly to business/marketing/product people, it was refreshing to listen to presentations about other things than code. In particular, I enjoyed great talks by Jeff Lawson, Des Traynor and Justin Rosenstein on the software people mindset, product management and effective company communication.

All in all I really feel like I got a great value out of this conference and would recommend it to anybody in tech. I met both new and old friends, learned a lot, found some cool products & services and got inspired to get home and create awesome stuff : )

Growing up with an interest in tech outside of the US gave me an almost mythical perception of Silicon Valley. I spent many years of hitting F5 while reading WWDC live blogs in high school and hearing stories about Xerox PARC from my software architecture professor in uni (who once worked there). Ever since I blew an interview for a Stanford student exchange program after studying hard to get top grades, I had felt a need to go to the valley in order to redeem myself. Now, this was finally happening.

On this occasion, I wasn't traveling alone but went with my great friend from high school, Stefan) and his colleague Robin. Me and Stefan were renting an AirBnB just south of the Mission district, which had become some kind of mix between Hispanic neighborhoods and hipster cafés where patrons were outnumbered by MacBooks. Unfortunately, Stefan didn't get a WWDC-ticket so he attended the increasingly popular AltConf instead.

Since this was the first WWDC for us all, we went for the keynote queueing experience at 4 AM. Of course we got in line just outside an alleyway acting as a massive wind tunnel. Freezing our asses off wasn't really what we expected of sunny California but the excitement of finally being there kept us cheerful through the early morning. Running into the Presidio chasing good seats felt surreal. Since the wifi was much better than expected, I couldn't hold my excitement together and video called some friends and colleagues eagerly awaiting the keynote in Sweden.

Already in the first minutes of the keynote, you could feel this time was somehow different. Everything started off with a video celebrating app developers all over the world. And then, Tim Cook announced that there would be three topics for the presentation: The Mac, iOS and developer tools. For a keynote that nowadays had become adapted for press and general enthusiasts, something was odd. Especially considering that most dev goodies are usually announced during the Platforms State of the Union keynote, just after.

When Craig Federighi uttered the words "What would it be like if we had Objective-C without the baggage of C?", everybody in the room looked at each other in confused disbelief. And as of that moment, the Apple developer community had a new language to learn.

The WWDC week was one of the most intense in my life. Every morning, we woke up early for a big breakfast and took our bikes to Moscone Center in time for the morning sessions. I would watch a session, queue for labs, then lunch, labs and sessions again. In between the madness, everybody rushed for coffee and bumped into friends running from one auditorium to the other. Then after the conference was closed for the night, there were dozens of parties and events for meeting up over a drink.

On Saturday just after the conference, me and Stefan rented a car to visit his relatives in Thousand Oakes, just outside Los Angeles. Resting my brain after a weeks worth of information overload was well worth and I hadn't driven a car since I started traveling. After meeting up with Stefans relatives we did some touristing all around the area. We went to Santa Monica, visiting the pier from the GTA games and of course worked out at Gold's Gym Venice: The Mecca of bodybuilding, where good ol' Arnold once trained for the Olympia :D

Even though Stockholm has a vibrant tech community, it doesn't even compare to what we witnessed sightseeing Silicon Valley. In cafe's and on benches in the street, there were college students stereotypically pitching startups ideas to venture capitalists in suits. We even encountered people discussing variable scoping, casually walking the pavement.

During the final days before heading back to Stockholm, we took a hike in the beautiful Yosemite National Park together with Peter Steinberger of PSPDFKit. We had been planning this since long before WWDC, but with the announcement that Mac OS 10.10 was named after the park it made even more sense.

All the administrative requirements for entering and camping in the park was very unusual for us as Swedes. We had to book a specific trail and there were regulations for where to camp and special permits to get. In Sweden you can camp anywhere you want unannounced, including on private property as long as you're not within sight of a residency.

In the end we decided on camping on top of the Yosemite Falls trail, giving us great views over the valley and some of its biggest landmarks. Although we were a bit disappointed that we didn't get robbed by bears, it was a great trip nonetheless.

After ticking off the mandatory tourist attractions in San Fransisco, it was time to leave California for a traditional Swedish midsummer in the Stockholm archipelago. With all the new stuff in iOS 8 and Swift, we all had a lot to digest. And what better way to do that then with some Swedish schnapps? :)

After staying in Brussels for a couple of weeks, it was time to move yet again. This time for giving Prague a second chance, a city I previously visited while horribly sick with a throat infection. Now that summer had come and everybody were on their vacations, I noticed a pretty huge price surge in flight tickets. After searching long, I finally found a pretty cheap flight from the Charleroi airport south of Brussels. Only problem, the flight was due to depart 06:30 and I was staying in a house outside the city.

Basically, my options was to either take a cab for 100€, find an AirBnB in the city (from where shuttle buses went all night) or take the cheap route and sleep at the airport. I was on my final month of traveling and money started running scarce, so I started to check around online how it might be sleeping at an airport. After all, this wasn't anything I've ever done before. Turns out, there is an entire community around it and I was even able to find reviews with tips for sleeping spots in my airport! So without further ado, I decided this could be an experience of its own.

The Good

Fairly clean floor

Plenty of room on floor

You're not alone in looking like a hobo

The Bad

It's an airport

Floor is hard

Guard woke me up at 03:50

The Verdict

Even though I didn't have any equipment prepared whatsoever, I managed to survive the night and get a whole three hours of decent sleep on the floor. Make sure you have something fairly soft to lie on and get a reservation for a chiropractor at your destination.

One of my absolute favorite classes in the Cocoa Touch framework is NSFetchedResultsController, because it makes data driven animations so easy to implement. Moving things around is how we organize in the physical world, which is why spatial position and animation of it is such an intuitive metaphor for dealing with digital objects.

In this post, I will show you how to push NSFetchedResultsController to and beyond its limits to achieve a fluid and intuitive user interface for organizing things in a table view. These are the topics we are going to cover:

The demo app

To demonstrate the powers of the fetched results controller, I have built an app. This simple task manager lets you enter todos with three different priorities and also has an option for showing a simpler list where priority does not matter.

To switch priority of the tasks, we could have used a detail inspector view, action sheet or cell swiping. Those are examples of indirect manipulation, making the user need to realize that changing an attribute of the task, results in the task being reorganized in the list. Rather than that, let us make the user just drag 'n' drop the task into the section where it would end up showing after manipulating the corresponding attribute. Direct manipulation gives instant feedback and a more natural interaction.

The data model

If we look at the data model file for this app, we see that the ToDo entity is very simple, containing what you would expect: a title, priority and a done flag. What is more interesting is that each todo has a mandatory relation with a meta data object, which is created upon insert.

Extracting meta data into a separate entity separates concerns and makes it easier if we would want to serialize todos to a web service in the future. In the app, the NSFetchedResultsController will actually be set up to fetch the meta data objects instead of the todos themselves. This will soon be explained why.

The first property of the meta data entity, internalOrder, is an integer which orders the todos within a section. It gets updated when the user reorders the list with drag 'n' drop.

The second property, sectionIdentifier, is a string used to divide the todos into sections. NSFetchedResultsController requires that the sections are sorted in the same order as the rows so they can be fetched in batches. Since the sorting attributes must be stored in the persistent store, that also means the sectionNameKeyPath must either be stored itself or derived from a stored property.

Every time a property affecting a todo's displayed section changes (such as priority or done status), the section identifier must be updated. In Objective-C we could accomplish this with property overrides or KVO but unfortunately neither of these techniques are easily available for managed objects in Swift (as of Xcode 6 beta 5). Instead we have to remember to manually trigger an update when doing drag 'n' drop or marking a todo as done.

Another nuisance is that NSFetchedResultsController assumes all sections are semantically equal and therefor always sorts them in alphabetical order. We get around this by assigning the
sectionNameKeyPath
to a Swift enum value with a method for getting the actual display name. This way, we achieve arbitrary sorting of sections. If we wanted to make the order of the sections dynamic, we could instead of using an enum, generate an identifier string runtime.

At last we have the ToDoListConfiguration. This object stores in which display mode (simple/prioritized) the table view is in. This could as well have been stored in NSUserDefaults or just in memory using state restoration between app launches. But since it affects the section identifier of the meta data objects, I found it suitable to have it connected in the persistent store.

As we setup the fetched results controller, there are a couple of things to note. First, the entity we fetch is ToDoMetaData and not ToDo itself. The reason is that this is where our sorting keys and sectionNameKeyPath are stored. The fetched results controller can be setup with key paths directing to a related entity, but it only keeps track of changes on its original fetched dataset.

Since the meta data object has a one to one relationship to the real ToDo object, we can easily extract the todo once we have the metadata. To make this perform better, we add "toDo" to the relationshipKeyPathsForPrefetching property of the fetch request. Else, CoreData would fire a fault to the persistent store for every single todo once they are displayed in the table view.

The fetched results controller delegate calls which notify of changes to sections and objects are forwarded to a separate FetchControllerDelegate class, which uses an implementation mostly like the example found in the developer library. It responds to the delegate calls by informing the table view.

Animating change of done-state and display mode

With the data model and fetched results controller set up, it is dead simple to produce data driven animations.

As we change done status, the meta data object will assign a new section identifier which the fetched results controller picks up to notify that the todo has moved from one section to another.

Switching display modes between simple and prioritized is even more trivial. This is where NSFetchedResultsController shines through, making the view controller light and not having to calculate which index paths should move where.

Semantic drag 'n' drop

In this app, reorder controls serve two purposes: to visually reorder todos and to change their state. You can move a task to the "Done" section to mark it as finished or between different priority sections. Both effects are pretty straight forward to achieve. The only thing to remember is to ignore the fetched results controller who will want to notify of the changes to the model.

Showing empty sections through a proxy

One of the bigger problems with NSFetchedResultsController is that it cannot show empty sections. This is because it derives sections from objects and not the other way around. Since we use reorder controls to change priorities for todos, we sometimes need to show empty sections for the user to drag todos there. The solution is to wrap the fetched results controller in a proxy object.

In this project, the ToDoListController class acts as a man-in-the-middle by forwarding delegate calls and section information from its fetched results controller and modifying them along the way. When the table view enters edit mode, the list controller generates the empty sections and tells its delegate that they have been inserted.

Since the fetched results controller is not aware of these "fake" sections, all index paths it sends must be converted to match the expanded table structure. ToDoListController does this by keeping track of which sections are known to the fetched results controller and what indexes they have there.

Conclusion

Hope you enjoyed this sample of techniques on taming the NSFetchedResultsController. You may have noticed that the app disables the display mode control in edit mode. I have left this as a final exercise, since I felt the necessary changes would clutter the code.

If you have feedback on how these techniques can be implemented even better (especially in these early times of Swift), hit me up on Twitter or send a pull request on the repo for this demo app. Thanks for reading!

My last travel update concluded just as I was leaving Rome to head for UIKonf in Berlin; a trip that Apegroup made possible by sponsoring my conference ticket. Since I had already booked a plane from Rome to Prague, I had to take the train the last stretch to Berlin. The timing was supposed to be perfect. I would go straight from the Prague airport to the train station and then arrive in Berlin in enough time to check in at my hostel and go to the UIKonf pre-party. Or so I thought...

Of course my train gets severely delayed and I end up an hour late in Berlin. "No problem", I keep thinking. "I'll just go straight to the party and check in my stuff later". So I did. Well there, I meet both old and new acquaintances and we end up drinking a few beers at a Russian bar. Time flies by and as my cab arrives the hostel, I notice something. The windows are dark and the reception door is locked.

Desperately, I try calling a telephone number which I then hear ringing through the door. Without any clue or WiFi in one of the shadier areas of Berlin, next to a drug dealer's nest (Görlitzer Park), I walk around to see if there's anything open. After a while I then realize there's a slim chance that some drunk tourists who already checked in at the hostel, might head back home to sleep. So instead, I resort to stalking people. After a few embarrassing moments I finally see a girl heading straight for the door. Luckily, she doesn't pepper spray me and believes me after I show her my booking confirmation. Since she had a free bed in her room, I stayed there and it later turned out to be the exact bed I was booked for anyway.

The next day UIKonf began, dubbed "The independent conference for serious iOS developers". Even though it only started in 2013, organized by Chris Eidhof of objc.io, it has quickly become a high-profile European event in the community. I originally planned to write a dedicated blog post about it, since it was so great. But as you will soon find out, unforeseen circumstances came in the way.

Depending on how you see it, UIKonf lasted two to four days. The day before the actual conference, there were several workshops you could attend with topics ranging from Core Data to Microsoft Azure and UI-design. After the two-day conference, there was also a hack day which spawned incredibly useful tools like Pod Roulette and gave people mind-blowing insights on the Berlin Metro ticket system.

The conference itself was hosted at Heimathafen Neukölln, a gorgeous theater whose name took me the entire week to pronounce properly. Between the presentations, you had your usual coffee breaks. Except the coffee came from Berlin's best coffee shop and was of a different mix every time they served. That level of detail was found throughout the conference. Even the badges were uniquely etched in wooden plates.

The talks had well varied topics with a higher focus on practical use than the many inspirational talks at NSConference. The sheer quality of content and presentation of the talks at UIKonf really surprised me. A rising theme among the speakers was to use custom, interactive presentation apps instead of the usual Keynote (or Chris' hot new Deckset). The animation guru David Rönnqvist started this off with a gorgeous, fully animated SceneKit app to explain how OpenGL works on the iOS platform. Then Nick Lockwood took over by doing realtime image loading benchmarks on a custom iPad app, containing all slides and everything. These guys really set the bar and I hope we will see more interactive presentations from here on.

On thursday night, the conference concluded with a party hosted by Facebook, who recently impressed the entire community with Paper and all the great open source projects they've released. Waking up on friday, I felt like shit. Thinking it was a regular hangover, I went to the gym to sweat out the last drops of alcohol in my body before going to Betahaus to hack. When I later crashed at my hostel dorm, I could feel that I was on the brink of getting really, really ill. Just as I was going to fall asleep, a bunch of girls enter the dorm, cheering, all ready for a night out. And of course, my stupid self gets convinced by them to join on their nightly quest.

The Berlin nightlife is famous for the underground techno scene and its notorious bouncers who reject party-going tourists like flies. We ended up with around 10 people trying to get in to some of the more prominent clubs. In Berlin, you can't just go in as a group. They're to cool for that. What you instead do is split up into pairs and spread throughout the lines so the bouncers don't get suspicious. While some make it in, others don't, seemingly random.

After a great night out, I woke up feeling even more shitty than the day before. Thinking my hangovers just stacked, I once again went to the gym (worst decision EVER). When neither that or eating a solid meal didn't help, I started to gain suspicion that I might have caught something.

Taking the train back to Prague, I knew for sure I was having a bad throat infection. As beautiful and lively of a city Prague is, I couldn't enjoy it much and just rested as much as possible. Before I could tell, my days in Prague were over and my condition was only getting worse.

Budapest was a city that really made an impact on me even though my condition was progressing towards abysmal by the hour during the entire stay. It has incredible beauty, lots of stuff to do, great people and awesome nightlife. Since this was my last stay abroad before chilling heading back to Stockholm in wait for WWDC, I booked the craziest party hostel I could find together with Chad, the guy I went hiking in Morocco with. This idea turned up to be both great and disastrous at the same time. Retox wasn't your run-of-the-mill backpacker hostel. The partying there happened from mid-day till dawn, every single day. In fact, when we arrived, the staff warned us that their neighbors hate them so much, they sometimes throw buckets of shit on bypassing guests. ¯\(°_o)/¯

On the first night we met Tyler. Tyler was an American guy who was getting married in Slovenia a couple of days later and was on Retox for his bachelor party... except he was alone. By some weird force in the universe, all his friends who were invited had different mishaps happen to them, which made them unable to come. So there were me and Chad, his new stag's mates. Later on, Chad even joined in on Tyler's wedding in Slovenia and stood on his side as a groomsman.

My life in Budapest consisted of three things: partying, curing the hangover from last day and abuse painkillers to stay afloat. My throat was so bad at this point that I had to take cough drops every hour just to be able to talk. Alcohol and four hours of sleep a night didn't exactly help but there was no possible way of avoiding the parties. One of the more remarkable events was the sparty, set in the Szechenyi Baths outdoor spa. Imagine a hot spring pool, a DJ, lots of tourists and alcohol. How could you go wrong?

After all the craziness in Budapest, I was ready to drop dead. Arriving in Stockholm I went straight to the doctor, who took one look at me and concluded I was in dire need of penicillin. I looked forward to meet all my friends in Stockholm again, but that was outright impossible in my then current state. I recovered as best I could for a couple of days and then, it was time for San Fransisco and my very first Apple World Wide Developer Conference :D

A long time has gone and suddenly there is less than two months left on my journey. The last months have brought several literal and metaphorical ups and and downs. What strikes me over and over though, is how many amazing people I have met and how each new person takes me by surprise. The experience has broadened my mind, to say the least. Without falling further into delirium, here's the story.

Last time I did a proper travel update, I was on my way to Morocco from Spain. I ended up in Marrakesh, "The Red City". Visiting an Arabic country for the first time, Morocco was a brand new world unlike anything I've experienced as a westerner. Although it took a while for the culture shock to settle, I later fell in love with the place. The atmosphere was so different from any European city, I've never felt safer walking down the street in the middle of the night.

Jemaa el-Fnaa, Marrakesh by night

As it happened to be, Chad – an American guy I met at the Castle Rock hostel in Edinburgh a month before, was staying in Marrakesh at the same time as me. After meeting up, he proposed to hike up Toubkal, which at 4 167m was the highest peak in the Atlas mountains. Since I'd never hiked in my entire life before, how could I say no?

To get on top of Toubkal, we first had to take a cab to Imlil, the last outpost where cars could get through. Since we arrived late, we stayed at a local bed & breakfast where we could also rent equipment. From there, it was a grueling 6 hour hike past goats and killer mules to the refuge camp below the peak. While I was staying the night inside the refuge, Chad and his newfound friend Matthieu (who he had met on the ferry to Tangier) tented outside.

Matthieu was a French guy who took budget traveling to an extreme. He always carried a tent and hitchhiked wherever he went, even when in the cold vastness of Iceland. All that hitchhiking had him built up his cardio, which made us feel like bulldogs with astma as he raced on in front of us.

After a freezing night at the refuge, it was time to climb up the peak. Conveniently enough, the entire trail was clearly visible on Google Maps, which made pathfinding a no-brainer. It took us roughly two hours through rocks and scree to get up and when finally there, the view and feeling of accomplishment was incredible!

On the way down we found some snow patches to have fun in. Having a snowball fight after hiking through the scorching sun in over 35°C was as surreal as it gets. During the final stretch before reaching camp, we walked past a group of 16-17 year old kids and slid down the final bits of snow. Just five minutes later as we were arriving at the camp, we noticed something had gone very wrong. People ran past us with a stretcher and then we got the news: One of the kids we just passed, slid down the same patch of snow as us but lost control. On-site doctors had a look and concluded the boy had fractures in his spine and skull and an emergency helicopter was called for. We never found out how the kid did, but it surely bummed out the hike back home.

I spent a couple of more lazy days in Marrakesh (trying to get rid of the blisters on my feet), before continuing my journey. At this point, I didn't have much planned in terms of where to go when. The iOS developer conference UIKonf was drawing near in Berlin but I figured I wouldn't afford after winning the WWDC lottery. I knew I wanted to go to Prague, so I planned my itinerary accordingly. After finding a ridiculously cheap (25€) flight ticket from Rome to Prague, i figured I had to somehow get to Rome from Marrakesh where I was staying. Turns out the cheapest alternative was to stay two days in Madrid.

Arriving to Madrid, I didn't really know what to expect. I love Spanish food, culture and climate but Spain had always been associated to beach life for me. In Madrid, of course, there were no beaches to be found. A couple of days earlier, I got an email from Fransisco Sevillano who read my Fluent Pagination post after it was featured in iOS Dev Weekly. He had checked my route, noticed I was in Madrid for a few days and invited me for lunch! I was once again struck by how many incredibly nice people there are in this community.

After several delicious Spanish tortillas and a great conversation, Fransisco told me about an NSCoder presenter night happening later that night in Madrid. He couldn't go himself so I thanked for the lunch and went on my own. The topic for the presentation was ReactiveCocoa. What surprised me though, was that the entire presentation was in Spanish. After spending several weeks in Spain, my Spanish was good enough for me to understand the presentation. Asking questions was more difficult. One of the organizers ended up translating my questions from English to Spanish, while the presenter answered me back in Spanish. Weirdest Q & A session I've experienced, but we all succeeded to communicate with each other in the end.

The next day, I had a session at the huge and super modern FitUp gym, which I highly recommend! At this point, I hadn't been to a gym since all the way back in London a month before. Calisthenics may be great, but I missed lifting iron. After an obligatory bar crawl to check the pulse of the city, my last night was over and it was time to head for Rome. All in all, I left with a much greater appreciation of Madrid than I ever expected.

Roman culture and history has always fascinated me. I was hooked by everything from Rome: Total War and the Spartacus series to Monty Python's Life of Brian. Actually walking among the old ruins and inspecting Colosseum in its full glory was immense.

The AirBnB place I got was in Santa Marinella, a tiny coastal town just an hour away by train. My host was so alike me, it was like stumbling upon a lost twin brother! He was born in St. Petersburg, just like me, moved away when he was six, as I did, a programmer (check!) and had a big interest in fitness (yup).

In short I had a very relaxing, although not that exciting stay in Italy. At this time, I had also talked to my boss at Apegroup about UIKonf and how I wanted to go but couldn't afford the conference ticket. Lucky for me, they were awesome enough to sponsor me, even though I was on a leave! With these news, I instantly booked a hostel in Berlin and train tickets from Prague. UIKonf was going to happen and I was super excited!

After WWDC and all the other madness in San Fransisco (which I haven't written about yet...), I took a pit stop in my home town, Stockholm, just as midsummer was lining up.

Midsummer is a big festivity with old traditions in Sweden, as accurately illustrated by a banned IKEA commercial. *ehrm* In essence, you gather your friends & family to eat herring and drink schnapps, preferably outside.

Traditional Swedish midsummer lunch with herring and boiled potatoes, among other things

For the fourth year in a row, I went out to my friend Oscar's summer house on an island in the archipelago, the beautiful crown of Stockholm's scenery. With the aid of good friends, fine schnapps, calm nature and 100 Mbit fiber I had a much needed, relaxing stay.

My other main objective in Stockholm except for midsummer and meeting friends, was to renew my passport which I finally collected today, wohoo!

Since my mom and I are going to visit my grandparents in Kazakhstan in the end of the summer, I needed to send away my passport to get a visa. At the same time I didn't wanna wait in Sweden all summer while the visa gets approved. So in the end we planned this crazy scheme where my passport gets sent to London for the visa, while I travel around in the Schengen area on my national ID. Then my passport will be sent to whatever country I'm currently in so that I can meet up with my mom in Istanbul (outside of Schengen) where the flight goes to Astana, Kazakhstan. Hope this works... *fingers crossed*

With two days left until I leave Stockholm, I already feel a bit bored and the urge to travel rises quickly. I've come to love Spain during this trip and my next stop Barcelona will surely be no different. This time I'm staying at an AirBnB in the centre of the city, close to clubs and co-offices alike. Hopefully I will get a nice, productive stay and my share of the sun before it's time to head for the 10th year anniversary of Tomorrowland Festival in Belgium :D

It's been another one of those long breaks since the last travel update. With a hellish fever lasting for over two weeks which still isn't over, I just haven't had the energy to write. Enjoying a penicillin pill from my AirBnB balcony in San Fransisco with WWDC just around the corner, things could be worse though.

In 24 hours I will be sitting in Moscone West, watching Tim Cook present the next engineering marvels from Apple, as he shepherds us developers to the creating of the next generation of life-improving services.

I reflect on the strange symbiosis app developers have with Apple. We devote our carreers and a big portion of our daily lives to create apps and services, putting an enormous amount of trust in a single company. At the same time, we all know iOS and Mac would never have grown to their extreme popularities without third party developers. We fuel Apple's economy, they fuel ours.

This might all seem a bit fuzzy but hey, the fever's doing the talking.

In issue #12 of the excellent objc.io publication, Joachim Bondo wrote an article about using the view controller transitions API introduced in iOS 7, for supporting animated transitions in a custom container view controller. He concluded with the following words:

Note that we only support non-interactive transitions so far. The next step is supporting interactive transitions as well.

I will leave that as an exercise for you. It is somewhat more complex because we are basically mimicking the framework behavior, which is all guesswork, really.

In this article we will do that exercise, based on the same container view controller Joachim left for us at GitHub.

If you are not familiar with the APIs for view controller transitions, I would suggest you start by reading Joachims article and its many, linkedresources. Also, note that even though all the API protocols seem to be safe to implement on our own, we will during this exercise find out that is not really the case. No need to worry though, there is always a way.

I spent most of my weekend trying to swizzle alloc, but then giving up and just solving it in raw assembly – Peter Steinberger

Setting the stage

Starting off from Joachims article, we are left with a ContainerViewController catering three child view controllers. The current UI for switching between the child view controllers consists of a range of numbered buttons.

When tapping one of the buttons, a PrivateTransitionContext object, conforming to the UIViewControllerContextTransitioning protocol is created. It holds state for the transition to the new child view controller.

Through the ContainerViewControllerDelegate protocol, a UIViewControllerAnimatedTransitioning animator object is fed. It is responsible for executing a pretty animation, conveying the transition to the user. If the delegate does not return an animator, the default PrivateAnimatedTransition is instanciated.

Finally, the ContainerViewController itself cleans up child view controller relations when the animation is over.

The challenge

Our mission, should we choose to accept it; is to provide an interactive transitioning between the child view controllers in the container.

Since the default transition animation is a horizontal panning, a sensible interaction would be a panning touch gesture across the screen. Users should also be able to cancel an ongoing interactive transition if they wish.

In addition to the default interaction, we should extend the ContainerViewControllerDelegate protocol so that other interactive transitions can be used. While different types of panning or pinching gestures are the most common inputs for interactive transitions, one could with a bit of creativity drive transitions using accelerometer data, button mashing, sound or even camera feeds.

Let's code

Just as in Joachims article, we will implement these new interactions in a few stages, namely four.

Stage 4: Adding a gesture recognizer

First, we prepare the interaction by adding a new pan gesture recognizer to the container view. This is done by the new PanGestureInteractiveTransition object, which at this stage only setups the gesture recognizer and lets the creator issue a block when a pan gesture begins recognizing.

With these few lines of code, we can trigger a transition to go to the next or previous child view controller when the user starts panning. At this point the transition itself is still non-interactive though.

Check out the stage-4 tag and its diff to see the changes compared to the original project.

Stage 5: Making it interactive

In order to make the transition interactive, we need to have an object conforming to the UIViewControllerInteractiveTransitioning protocol. It is a simple protocol containing only three methods:

At the start of a transition, the ContainerViewController checks if the transition should be interactive and either calls startInteractiveTransition: on the interaction controller, or animateTransition: on the animation controller.

In this case, we want the animation executed by the animation controller to be drived by the interaction controller. Now you might wonder how that is done. The answer is (usually) UIPercentDrivenInteractionController. This is what we would have used to achieve the same effect on a UINavigationController or a UITabBarController. Let's try!

Tying animation and interaction together

UIPercentDrivenInteractionController is an object conforming to the UIViewControllerInteractiveTransitioning protocol, providing an easy way to control whichever animated transition that gets thrown at it, as long as it animates through the UIView or CoreAnimation APIs.

In addition to the the protocol implementation, it has only a couple more methods which are used to report progress on the transition.

With these methods and some Core Animation magic, the interaction controller controls the flow of the animated transition.

Now we already have our PanGestureInteractiveTransition that holds a pan gesture recognizer. By making it a subclass of UIPercentDrivenInteractionController, we can use that object as our interaction controller and let it report progress up the class hierarchy when we're panning.

If you've been paying attention up to this point, you might still wonder how and when the actual animation controller gets fired. Because, when we have an interaction controller, we no longer call the animateTransition: method that initiates the animation.

Firing the simulator, we actually find out that Apple is cheating a bit.

As soon as we start panning the app crashes. Looking down the call stack, we can see that UIPercentDrivenInteractiveTransition looks for the animator in our context, calling an undocumented method. Conveniently enough, all Apple-made transition contexts implement this method and that's how the percent driven transition can fire the animation. Unfortunately, that means we cannot use the class for our own custom container view controllers.

Enter AWPercentDrivenInteractionController – a drop-in replacement which is fully API-compliant unlike Apple's own implementation. By changing the superclass of our interaction controller to AWPercentDrivenInteractionController and adding one extra line in the setup, we have a working, interactive transition.

self.defaultInteractionController.animator = animationController;

At this stage, we have interactive transitions that work but without cancel support. To see the complete code for this stage, checkout the stage-5 tag or view the diff to see the changes.

If you are interested in the inner workings of AWPercentDrivenInteractionController, look at Appendix A below, or in its separate project on GitHub. The class is also released as a cocoapod with the same name.

Stage 6: Abort!

When users start an interactive transition, they expect being able to cancel it. Just as they can with the pop transition in a navigation controller, we will now make sure they can with ours too.

To enable cancellation, we need to do a bit of work both with our context and the interaction controller. Since all of this already is supported through UIKits protocols, it is not too hard to figure out how to implement. We start off with the changes in PanGestureInteractionController.

At the moment, the interaction controller always calls finishInteractiveTransition when the pan gesture is ended. We can use different criterias, including velocity of the touch, to take the decision on either canceling or finishing the transition. For this example, we just use a simple progress check.

When we run cancelInteractiveTransition, AWPercentDrivenInteractionController forwards the message to our transition context. So let's implement the callback in PrivateTransitionContext.

First of all, we add a new Bool property to replace the hardcoded transitionWasCancelled method which always returns NO. We do this in the class extension, since the public getter is already declared by the UIViewControllerContextTransitioning protocol.

@property (nonatomic, assign) BOOL transitionWasCancelled;

Then we implement the two callback stubs that get called by the interactive transition.

Remember that the transition context is just a holder of state, it does not actually do much of its own. We now have to check the state in the completion block ContainerViewController defines and react accordingly.

Another small detail is that we now need to hold on updating the selection states of our navigational buttons before an interactive transition actually has completed. You will find that this change is implemented in the code with the stage-6 tag. To see what change since stage 5, check the diff.

In the best of worlds, we would let the buttons animate along with the transition. That will be left as the final exercise for the reader. In essense, one would use the updateInteractiveTransition: callback on the context to drive the animation forward.

Stage 7: Delegation

In this final stage, we will enable delegation of interaction controllers through the ContainerViewControllerDelegate protocol. Just as we already do with animation controllers. We add a third delegate method to the protocol:

The common pattern among Apple's implementations is that the interaction controller is dependent on the animation controller, but not the other way around. If the delegate returns an animation controller, it gets the chance to provide an interaction controller too. But it cannot ever control the default animation, since that may change at any notice. Here is a table that shows the possible combinations:

There is only one step left until our API is complete for delegating interactive transitions. If someone uses our ContainerViewController and wants to vend their entire own interactive transitions, they probably want to disable the interaction controller already built in. We look at UINavigationController for inspiration:

It is a simple solution to expose the gesture recognizer that triggers the default interaction transition through a readonly-property. Since UIGestureRecognizer has an enabled property, anyone using our class can just disable the recognizer to disable the default interactive transition.

Since UIGestureRecognizer has an enabled property, anyone using our class can just disable the recognizer to disable the default interactive transition. Note also that we in the public interface cast it as a plain UIGestureRecognizer without specifying that it recognizes a pan gesture. This is the highest, useful level of abstraction. Remember: whenever possible, code against an interface, not an implementation.

Now our ContainerViewController is fully catering all needs for both custom animated AND interactive transitions. With this separation of concerns, the container view becomes incredibly powerful as transitions can change dynamically while the app is running, just from our public API.

The final code for this project can be found at the stage-7 tag. Just as before, there is also a diff against the previous stage that you might be interested in.

To test the delegation of interaction controllers, there is a small, fake interaction class that drives the interaction entirely by itself inside the app delegate. By un-commenting the lines setting the delegate and disabling the default interaction, you can see it in action by pressing any of the transition buttons.

Conclusion

In this article we have learned how to implement the iOS 7 view controller transitions API for adding interactive transitions to a custom container view controller. In iOS 7-land, this is expected of all general containers and now we have done our part.

The newly introduced view controller transitions API has its rough edges, something that becomes apparent when trying to implement interactive transitions with the framework-provided UIPercentDrivenInteractiveTransition. Perhaps this is something that will be remedied in the next major release of iOS. With just days away from Apple's World Wide Developer Conference, we may soon find out.

Even though we worked long and hard, there is still one piece of the transitions API still missing: the UIViewControllerTransitionCoordinator. This is a protocol that enables other animations alongside a view controller transition.

As mentioned earlier, a nice thing would be to animate the state of the buttons as a transition progresses. This could be done by using the transition coordinator. I invite you to take that challenge :)

Appendix A – AWPercentDrivenInteractionController

AWPercentDrivenInteractiveTransition is a drop-in replacement for UIPercentDrivenInteractiveTransition for use in custom container view controllers.

When an interactive transition starts, AWPercentDrivenInteractionController freezes all animations inside the transition contexts container view by setting its layers speed to 0. It then calls the animation controllers animateTransition: method, which adds the transition animations to the layer.

The interactive transition object is now in full control of all the animations residing in the container view.

To make interactions drive the animation forward, the timeOffset property on the container view layer is adjusted during interaction callbacks. This renders the layer as if it was in mid-animation even though all animations are technically paused.

Since animation is controlled by timing, the animation curve used is very important for the resulting feel of the interaction. When aiming for direct manipulation, use UIViewAnimationCurveLinear in your animated transition.

Finishing

The mechanics of finishing an interaction is very simple. Basically, the layers speed is reset to 1.0, beginTime is set to the old timeOffset and timeOffset is reset to 0. This makes the animation complete just as it usually would, beginning at the same point in time as we rendered before the interaction was completed.

We are also relying on the animator object to call completeTransition: on the transition context once the animation is completed.

Cancelling

Cancelling transitions turned out to be somewhat more complicated. Even though it should be possible to set a layer's speed property to -1.0, I never got this to work. Instead it is done the old-fashioned way by using a CADisplayLink:

12:00: Walking to the beach to get one last dip in the Mediterranean Sea.

13:30: Catching the bus to Tarifa after running through the city in usual manner.

16:00: Arriving in Tarifa, meeting an American family and walking from the bus stop to the port.

17:00 (GMT +1): Getting onboard the katamaran to Tangier. Quite a rough ride, glad my motion sickness pills from the bus are still in effect.

17:00 (GMT): Landing in Tangier. Sharing a cab with an Estonian stewardess from the ferry company who recommends me to buy first class tickets for the train to Marrakech, "Second class is dangerous".

17:30: Buying tickets at the train station. After first thinking my train would leave in just one hour, began realizing I just switched time zones and was mistaken about the train departure time. 3 hours to kill.

17:30: Walking at the beach. "Friendly" guy starts talking to me, shows me around. Insists on showing the local brothels, gets disappointed when I tell him I'm not interested.

18:00: Arriving in the city center. "Friendly" guy asks for a tip of 20 dirhams, not much considering the long walk. Taking a shawarma plate to still my hunger.

19:00: Wandering around in Tangier, taking note of several locals telling me "Where are you going? There are no hotels this way".

20:00: Overrated my sense of direction. No cached maps on my iPhone, just the compass. Checking the compass, realized I've been going the completely wrong direction all the time.

08:00: Waking up in the cabin, arriving in Marrakech. Grabbing a glass of orange juice and a chicken panini for breakfast and WiFi. Checking walking directions for the Equity Point hostel and caching up maps.

10:00: Arriving on the spot I thought the hostel was located at, none to be found. Starts thinking of backtracking to the point where I could follow walking directions.

10:15: Asking a local for directions. Good and bad idea. Turns out there's two streets with the same name, I was at the wrong one. Follows local who tells me to walk 100 metres behind him, else he could get in jail. Fishy enough.

10:30: Arriving at Equity Point hostel. Slips a 20 dirham tip, just as in Tangier. Turns out this local is a bit more greedy, telling me he usually gets 400 dirhams from American families (~40 €). Local gets upset, demanding at least 100 dirhams. Finally, gives him 50 dirhams to avoid trouble.

10:45: 3 hours to kill until check-in. Tries out wifi, turns out it sucks. Starts reading Javascript: The Good Parts by the pool.

Today I put my imaginary tourist hat on and went on a day trip to the Guadalest valley, ranked no 1 of all the attractions in the Alicante area on Tripadvisor.

Of course I knew this was a tourist trap, but my dear AirBnB host had begun hinting that I should do something else than programming and going to the beach all day. And to be honest, it looked kind of nice.

To get to the valley I had to take the tram to the neighboring, tourist-flooded city Benidorm and then a public bus. This bus only went once a day so I needed to have precise timing in order to not miss in.

In my usual manner I calmly ate my breakfast for way too long and ended up running 2K, catching the tram thanks to a well timed red light with 5 seconds to spare. Perfect timing.

On the bus, I noticed how I was the only one younger than 60, except for one chinese girl who seemed to avoid any social contact no matter what. I didn't care much though, since I enjoy exploring things alone anyway.

Well at the valley, the tourist trap was even worse than I thought. The place was crawling with fat, elderly people, eating crap food for outrageuos prices. The views were sick though!

Looking out from the the established view point, I noticed a distant ruined tower on top of a rock. It looked like it wouldn't be a problem climbing it. Since there wasn't anything to do in the village anyway, I went for a little adventure.

After approaching the rock from a few different angles with no good path to be found I encountered a man with a donkey. Asking him about the way in my crackling Spanish, he showed me a hidden path between some rocks on the cliff-side.

Hidden path between the rocks

The path was way steeper than I imagined.

I had to fight my way through thorn bushes and past snakes to get to the top, but standing on top of the wall with a view of the entire valley, knowing that envy tourists were probably wondering what crazy person I was from the other side, made the entire trip worth it.

View from top of the tower walls

All in all the roundtrip cost me about 12€ + 2:50€ for the most expensive popsicle ever. Well worth it, as long as you stay away from the crowd.

Pagination of iOS Table Views, Android List Views and on the mobile web is a common way of circumventing the technical limitations of power hungry mobile devices and slow mobile networks when dealing with large datasets.

The classic implementation of this is to expand the scrolling area when new chunks of data are fetched, either by using a "load more"-button at the bottom, or automatically as the user scrolls down. Although this technique is very common, it has several usability drawbacks.

In this post, I'm proposing a more fluent approach for handling pagination within a finite dataset, using placeholders and without altering the scrolling area for the user.

There will also be an iOS sample implementation for UITableView and UICollectionView, including a datastructure for abstracting pagination which I'm releasing as a CocoaPod. More on that further down.

UPDATE 2015-03-08: I have now created a new, Swift version of AWPagedArray, the data structure used in the iOS example implementation. The Swift version is simply called PagedArray and can be found on GitHub.

So what's wrong with expanding a scroll view?

There are in my opinion three big problems with expanding a scroll view as you load more results.

First, it makes for a choppy scrolling experience when the user hits the bottom of the scrollable area multiple times. It's like catching red lights while driving. This can of course be mitigated by preloading the next results page as the user approaches it, but that doesn't help users who quickly wants to reach the bottom in a sorted list. This leads us in to the next flaw.

The technique is also ill-suited for working with sorted and sectioned results. Since the scroll view expands in a certain direction, you have to load all results to get to the other side of a sorted list. For sectioned results such as in alphabetical sorting, you need more UI than the scroll view itself to quickly jump to a particular section, since the user can't scroll that far into the dataset.

"This category can't be that large, I'll browse it all"

Finally, the scroll indicator loses its function of indicating where the user is in the current dataset. Thus, the user needs another interface element to inform of the set's size. It also makes it difficult to navigate back to interesting items since you can't memorize the scroll position. I remember in particular browsing an e-commerce app thinking "This category can't be that large, I'll browse it all.". After pressing the "load more"-button ten times and still not being done, I had to give up and find ways to refine my search.

Fluent pagination

Figure 2. Fluent paging example

The method I propose for handling pagination aims to be as least obstructive as possible, minimizing UI and giving the user the illusion of data always being there.

Instead of making it very obvious to the user that data is in fact paginated by restricting scrolling, pages of data load fluently without scrolling being hindered. Placeholder views are laid out as soon as the total size is known, and views representing data animates in gently as results are populated. This enables the same interactions as if the entire dataset was loaded at once. Users can quickly scroll to the bottom or to any section while the scroll indicator always shows the current location within the entire dataset. Also, when quickly scrolling past pages, loading operations can be cancelled, improving performance and saving bandwidth.

Note that this method only works well with finite datasets. But even if you would, say create a client for a Twitter-esque service, you could limit the results you actually display in one view to a couple of hundreds or so and still use this technique for paging. One could also combine fluent pagination with traditional scroll view expanding for a compromise that works well with ininite datasets.

Web service considerations

Of course, for all of this to work there needs to be a good API on the service catering the scroll view with data.

The one bit of extra information the client need in order to implement fluent pagination is the total size of the dataset. Then there's the actual paging mechanism: how to set page sizes and offsets. Now there's a lot of discussion about how these sorts of metadata should be delivered using a REST-ful service. Either go with putting links in the header (see RFC 5988), or if you have trouble accessing header values from the client, envelop the actual data and put metadata in the body.

Sectioned results

Dealing with grouped results in a fluent manner requires additional metadata from the API. In this case, you would probably want an API-call for just getting the metadata, and then construct URL's to access different sections

Of course pagination within sections could be implemented using techniques mentioned above.

iOS implementation & sample Code

UPDATE I have now created a new, Swift version of AWPagedArray , the data structure used below. The Swift version is simply called PagedArray and can be found on GitHub .

For the client implementation, I wanted to go with a solution which in code is as transparent as the user experience. The model layer holding the data should provide an API that as closely as possible mimics working with a static dataset. Details about how the paging works should be deep inside the model, with the view controller just getting callbacks when new data is fetched.

The most crucial piece in this puzzle was creating a datastructure that could support paging with a clean, familiar API. My inspiration for the solution was CoreData and more specifically, NSFetchRequest.

The magical fetchBatchSize property

Many have surely used the fetchBatchSize property without thinking of it's implementation details. It basically lets you batch CoreData fetches so that you can have a table view with thousands of cells, without loading all data objects from the store preemptively. Let's check the documentation:

If you set a non-zero batch size, the collection of objects returned when the fetch is executed is broken into batches. When the fetch is executed, the entire request is evaluated and the identities of all matching objects recorded, but no more than batchSize objects’ data will be fetched from the persistent store at a time. The array returned from executing the request will be a proxy object that transparently faults batches on demand. (In database terms, this is an in-memory cursor.)

Now the highlighted line is very interesting for our purposes. When setting the fetchBatchSize, an proxy object is returned. This proxy acts just as a regular NSArray with the size of the entire dataset, meaning the receiver can interact with it, oblivious of it's true nature. But as soon as an object outside of the already fetched set tries to be accessed, a synchronous fetch to the datastore is triggered. That way, batching is completely transparent. Although a database fetch on a flash disk is much quicker than doing mobile network calls and can be done synchronously, we can use the same principles for an asynchronous solution.

Fluent paging architecture

Figure 3. Fluent paging architecture diagram

AWPagedArray & DataProvider

AWPagedArray is an NSProxy subclass which uses an NSMutableDictionary as its backbone to provide transparent paging through a standard NSArray API. This means a data provider can internally populate pages, while the receiver of data is agnostic of how the paging actually works. For objects not yet loaded, the proxy just returns NSNull values.

What's interesting about NSProxy subclasses is that they can almost completely mask themselves as the proxied class. For example, when asking an AWPagedArray instance if it's kind of an NSArray, it replies with YES even though it doesn't inherit from NSArray at all.

After instanciating the paged array, the data provider sets pages with the setObjects:forPage: method while casting the paged array back as an NSArray to the data consumer (in this case a UITableViewController).

Through the AWPagedArrayDelegate protocol, the data provider gets callbacks when data is access from the paged array. This way, the data provider can start loading pages as soon as an NSNull value is being accessed or preload the next page if the user starts to get close to an empty index.

Since the delegate is provided with a reference pointer to the return object, it can also dynamically change what gets returned to the consumer. For instance, replace the NSNull placeholder object with something else.

UITableViewController & UICollectionViewController implementations

With a solid model layer, the view controller implementation becomes trivial. Notice how the dataObjects property can be accessd just as a regular NSArray with subscripting, even though in reality it is an NSProxy subclass.

As the dataprovider loads new pages, it calls back to the view controller through a delegate protocol. This way, if there are placeholder cells on screen, they can be reloaded or reconfigured with the new data.

Conclusion

As designers and developers, we should always strive for minimizing UI and hiding implementation details wherever possible. I believe that this approach to paging fulfills those goals and it has been shipped in big apps with great results. Even though the sample implementation in this blog post is for the iOS platform, the technique itself works on Android, the Web and other platforms as well.

It's always a challenge creating services for devices with constraints on power and connectivity. But using techniques like this, the user doesn't need to be aware of it. That's when technology becomes magic.

Ever wondered what kind of gear a traveling iOS developer might need for a six month trip? Soon you know. The inspiration for this post was Maneesh Sethi of the popular Hack The System blog that I read many times while dreaming about this trip.

Since I'm traveling around a lot in Europe where there's tons of cheapairlinecompanies, I opted to go with hand luggage only. Of course, I then had to fit with the before mentioned airlines' ridiculous baggage allowances.

Here's a video showing all I got:

Making it all fit

Samsonite expandable laptop backpack

I've had this backpack for many years and even though I can't find it online, it has never let me down. It has two main compartments with a cushioned laptop pocket in the back and lots of mesh pockets in the main.

It seems very small when you look at it, but as you can see, you can fit a lot of stuff in it.

The main compartment can also be expanded which is awesome. Every time I board a cheap Ryanair flight, I compress the bag and put as much on me as possible. When I then land and if it's in a warm country, I can just expand the bag and put all the heavier clothes in there again.

Everest light shell jacket

This jacket got everything I need. It's light, protects against the weather and also, it can surprisingly enough fit an iPad Air in one of its pockets! I wrote about it when I first bought it and after traveling with it for a month, I can say it was a great buy.

The one really bulky object I have with me is my smart shaker. Even though it's super practical when I'm actually using it, it takes up huge amounts of space. That's why I usually attach it to my backpack instead of putting it in. Of course that's something cheap airlines aren't really fond about. With this shell jacket, I can easily fit the shaker inside one of my pockets, no worries.

Since my iPhone 5 from work is locked to Three in Sweden, I needed another device for mobile data abroad.

Now, when I was getting a new device, I thought I might as well go for an Android. That way I would also have something to lab on if I try out developing android apps. Plus, it would probably be a lot cheaper.

I had the following criterias:

Should run KitKat

Can't be sluggish

Have a reasonably sized screen (apparently hard these days)

Cost significally less than an iPhone 5S

Turns out, I had a perfect match with the Motorola Moto G. I opted for the 16GB version and boy was I surprised when I saw the price tag of 200 €.

If you want the specs and a complete review, check out your favoritetechsite. But here's what I have to say after traveling with it for a month.

Everything is perfectly adequate with this device. Especially for someone like me who's traveling and wants something for checking twitter, facebook, instagram and searching some maps. The only real downside is the camera, where my iPhone 5 outclasses it.

No slugfest to be found, no crazy layers on top of standard Android and sure it doesn't have 4G but 21Mbps HSPA+ is good enough for me. You get two of these + a good night out for the same price of an iPhone 5C and quite frankly, if it just had a better camera I would leave my iPhone in my backpack.

Summary

The good

Are you friggin' kidding me about the price?

Great performance

Adequate battery

Runs KitKat

The screen is neither sized for basket ball players, nor infants

The bad

The camera doesn't compare to high-end devices

No 4G LTE

No microSD Card-slot

No NFC (but who cares?)

Verdict

If you want an Android as your second device or just don't care about phone photography, go get it!

One month have gone and I've been absolutely terrible at keeping the blog updated. Getting stuff done has in general been extremely hard since it takes a long time to create routines while constantly traveling. Every time I go to a new place, I need to find out how to get around, somewhere to work (proven to be hard), a grocery store, a good enough gym, supplements store, etc. Also, although hostels are cheap and you meet great people, everybody is on holiday and you get constantly tempted to go out partying.

After many rough weeks with long nights and bad habits, I've finally calmed down staying in a beautiful AirBnB house near the beach in Alicante. My hopes are that I will be able to become productive and live a good life here for a while.

Playa de San Juan, Aicante, 5 minutes walk from my current stay

Anyhow, since that's a different story, here's a recap of what I've actually been doing since NSConference in Leicester.

The Athens of the North

Edinburgh Castle, as seen just below Castle Rock Hostel

Straight after NSConf, I was going to Edinburgh to visit friends and meet up with some Scottish devs. The night before I had a chat with a friend and coworker who was doing her master's studies in Edinburgh about where I was staying. With 30 minutes left to cancel my previous booking, she convinced me to instead book the Castle Rock hostel. Since it was the first hostel I've ever stayed in, I didn't know what to expect. But now when I've been to a couple of ones, nothing beats it. Everybody was super friendly, the staff lived at the hostel themselves and they arranged awesome pub crawls and parties.

"Paint me like one of your french girls"

One of these events was a weekly beer pong tournament, a first for me. Everybody was randomly arranged in teams and I ended up with a New Yorkian guy we dubbed Captain America. After failing miserably the first match with my team mate having to cover for me, I got the hang of it as we progressed in the bracket. Winning with more and more margin, we ended up as champions and got to enjoy the spoils of victory at a nearby club. :D

Anticipation is high for the beer pong tournament at Castle Rock

It wasn't all partying in Edinburgh. I also attended some meetups that Marius Ciocanel told me about. There I met Markos 'qnoid' Charatzas who earlier gave an interesting speak about sound debugging at NSConf and Mike McQuaid from GitHub. One meetup I particularly enjoyed was the Product Tank, hosted in Skyscanners office next to the gym I went to. It was a first time for me heading to a product management meetup and I found it super interesting to discuss with people that have other perspectives.

Debate panel at the Product Tank meetup in Edinburgh, me on the right

All in all I really enjoyed Edinburgh. Everybody was super friendly, there was lots of tech people and the views were magnificent.

Casual programming from Arthur's seat volcano in Edinburgh

London

Kneeing Adolf in the nuts at Madame Tussauds, London

Street lunch in London

After Edinburgh I went on to London to meet up with a bunch of people. For the first few days, my mom came from Sweden to visit me and do some touristing. So after that I went on visiting the new Apegroup London office and going to some meetups. Sadly I missed out on the London iOS Developer Group with Dave Verwer (curator of the awesome iOS Dev Weekly newsletter), among others. Without knowing anybody, I signed up and went to the bar where the meet was. Turns out the bar was pretty big and I didn't recognize anyone. So after looking around for a while and trying to get hold of people through Twitter, I gave up.

Besides surprising my colleagues back in Sweden by turning up for the weekly meeting (with the London office Skypeing in), not that much exciting actually happened in London. I really wanted to go for Startup Weekend but unfortunately I was way too late with my application.

Also, I never would have thought it, but I found London way to big for my taste. Wherever you went it was at least a 30 minute commute, even within the centre of the city.

Appsterdam

Moving on to Amsterdam, I stayed right in the centre of town at the Flying Pig uptown hostel. Within 10 minutes I had found two drinking buddies and we went on to roam the night. The nightlife was awesome with every bar having a good DJ and dancefloor, even went it wasn't a proper club.

A Swedish app maker, an American actress and a Brazilian DJ, out to make the Amsterdam streets dangerous

Next day I went to visit the Appsterdam community at A-lab, just north across the river from the central station. After a lunchtime presentation about Sencha Touch, I had a coffee with the very friendly Patrik Beeker who also showed me around in the area. Working a bit in the awesome co-working space and walking around in the city, I got a great feeling about Amsterdam. Too bad I was due to leave just the day after. Reflecting on it now, I'm definitely going back to stay longer.

Peeps working at Appsterdam HQ

My stay in Amsterdam concluded by the mandatory Flying Pig pub crawl. Only problem was that my flight to Valencia was due for lift-off at seven in the morning, so I figured the best idea was to keep on going all night and then head straight for the airport, which I did...

Valencian football and decay

Last week I stayed in Valencia and frankly, got no work done whatsoever. Five minutes after walking inside of the Purple Nest Hostel, I met a german guy who told me about a football match the same night. I've never been that much interested in watching football, but now when I was in Spain, I couldn't miss the opportunity. I knew that a week later, the Copa del Rey final between Barcelona and Real Madrid was going to be played in the Valencia stadium, but the ticket prices were outrageous. This match however, was between the local Valencia CF and the Swiss team FC Basel in the Euroleague with tickets for a measly 15€.

First live football match of my life, Mestalla stadium, Valencia

The match was a rematch from which Valencia came out losing 3-0. Naturally, the crowd wasn't too excited as the referee blew the starting whistle. But then Valencia started to absolutely dominate the match, scoring more and more and leading with 3-0 as the regular match time ran out. Since I never knew about the previous match, I almost left while everybody else waited for overtime. In the end, Valencia won with a whooping 5-0 and the crowd went absolutely crazy, hugging strangers and chanting songs while exiting the arena to party on the street.

Getting to Alicante

After partying for five nights straight, me, a Belgian teacher and a kid from Finland went to stay two nights in Alicante just two hours down the coast from Valencia. Getting there was another story though. After having no luck finding ride sharing through BlaBlaCar, we checked the train schedule and decided to go by train instead.

Arriving at the station we thought the train left from, turns out it was the wrong one. Now we had to take the slowest shuttle bus ever to the other station just a few hundred metres away. With only 10 minutes left until departure, we ran towards the ticket vending machines when the next problem turned up: we couldn't pick Alicante among the destinations in the machine. By some odd reason, these particular tickets could only be bought in the manual ticket booth. After trying to convince some grumpy old people to let us pass to the front of the queue, things were starting to get desperate.

It was 5 minutes until departure. We already knew we couldn't go through the glass gates to board the trains without a ticket, but with desperation kicking in we ran towards the gate guard, begging him to let us through anyway and buy a ticket on the train. While he refused us and turned around, the Finnish guy found a leftover ticket on the ground and it actually still worked! One by one, he stood on the other side, opening the gates for the rest of us while the guard stood literally two metres away from us. Running towards the platform, we made it with seconds to spare!

Tense moments on the train to Alicante

While we made it to the actual train, we now had to face the problem of the ticket inspector. Since we were pretty sure we couln't buy tickets on the train, we figured our best bet was to pretend to be asleep so the he wouldn't want to disturb us. After some tense 30 minutes, we spotted the inspector walking down the wagon. Taking a quick look at one another, me and the finnish guy entered sleeping position. Suddenly, I heard the Belgian guy Simon (who taught Spanish) starting to talk with the inspector. I knew Spanish good enough to follow the conversation but not to explain the situation as well as Simon did. Finally, the ticket inspector let us stay on the train and get tickets. Although we paid 10€ more than we originally planned, this was considerably cheaper than taking a fine.

Tabarca, the smallest permanently inhabited island in Spain

As we arrived in Alicante I immediately fell in love with the place. The atmosphere was much calmer than in Valencia or London and the beaches were stunning. Still, there was a lot of young people from the University and the night life more than adequate. Thus, I decided to stay here while the others went on to other places, something I know I will not regret.

Woke up this morning with a pleasant surprise in my mailbox. After last years madness with tickets selling out within two minutes, Apple decided to run a "lottery" for this years WWDC. When hearing rumors that attendees were selected by their App Store presence, I thought I would never get a ticket but somehow, I did! So this year, I'll be attending Apple's World Wide Developer Conference for the first time :D

If you want cheap mobile data, get a 3 (Three) Pay As You Go Mobile Broadband SIM. For a measly 2£ at the nearest WH Smith (there's a lot of them on airports), you get a starting allowance of 1GB data. As soon as that runs out, just buy another SIM and repeat!

I did this once a week during my three week stay in the UK and except for the London subway, the network ran flawlessly!

The SIM-card works as well on your smart phone as on a tablet or MiFi device. Also, since it's meant for mobile broadband, tethering is allowed unlike with many other pay as you go SIMs.

I have a confession to make.

Three weeks into my trip, I am starting to realize how naive I have been. In my wild fantasies before traveling was reality, I imagined all the near-infinite time I would have on my hand. Compared to doing 8 hours of work on the same project day in and day out, I was surely going to be ten times more productive in a new environment. Boy I was wrong.

It's probably just a matter of getting accustomed to being on the road, but the latest weeks have been devastating in terms of actually getting things done. I've been finding myself spending more time on finding the best & cheapest hostel, flight route, grocery store, gym, supplements store and so on than actually being productive with writing & coding.

With all that said, I'm slowly finding calm in midst of chaos. Saying no to going out and being able to think straight in a chatty room is still hard, but it's progressively getting easier.

Here's an update of what I'm actually working on and topics for upcoming posts

First of all, I've been working for a while on this lengthy blog post about pagination. This one I should have written already back in 2012 when I implemented the fluent pagination technique I'm proposing, in the ICA Handla app. The post will feature thoughts from a UX perspective and how that affects UI in apps, together with client and server considerations and some iOS sample code.

There will also be posts with travel tips for digital nomads and lifters, including how to get cheap mobile data, gym passes, nutritional supplements and places to work, among others.

The thing that still worries the hell out of me is my economic situation. I really need to do marketing for my currently only paid app Min Firma, but that's a topic for another post. First, I need to become productive.

I'm staying here in London until tuesday and then I'm gonna visit the Appsterdam peeps. Really looking forward to that even though I'm just staying for two days. Then it's off to Spain where I'll probably be traveling around for a month or so, trying to achieve that programmer dream of sitting with your laptop on the beach and watching the sunset with a drink in your hand. Those will be good times :)

So this week I was at NSConference 6, one of the largest iOS & Mac developer conferences in Europe, hosted by Scotty of iDeveloper TV. Last year, I was there for Apegroup, this time, for myself. I really had a blast, meeting lots of new people and listening to talks that never ceased to surprise me or tease my mind.

The conference was hosted for the second year in a row in the art deco-styled venue Athena, which catered all needs except for good wifi. Lunch & dinner was included for all conference days (with the optional Curry Night) and the food was actually pretty good. What I also like about the conference is that all talks run in serial, meaning everybody have a chance to see all of them.

While all of the talks were great, some of them really made an impression on me. One I found particularly interesting was Karsten Kusche's talk about moving away from plain text source code languages, coming from a Smalltalk background. Coincidentally, Jason Brennan wrote a blog post about his own views on non-textual developer environments just the day before and got featured in iOS Dev Weekly. All in all, I think it's great that people are questioning the heritage software development stands on. Is writing ASCII-characters and storing them in plain text the most easy to understand and expressive way to describe what a piece of computer software should do? It's worth thinking about.

It was also interesting to see some controversy among the speakers. For example, while James Thomson spoke about the importance of code reuse and how it enabled him to reach new platforms, Marcus S. Zarra stressed that using third party software is risky and that it's better to write your own single purpose code. There has been a lot of debate around third party libraries and CocoaPods lately and it seems it won't end for a while.

Even though the conference schedule was tight, I managed to get to the gym at least once. I even got accompanied by the swole UI-Kit wizard, Peter Steinberger. It was kind of hard to find a gym in small Leicester for just one day, but after browsing the web for a while I found the site PayAsUGym. Basically, you can sign up there and find gyms all across the UK with day/week/month passes without having to sign up for a direct debit. The service itself was pretty good, and since we got a 5£ credit for joining, we ended up just paying less than 2£ for the stay at Spirit Health Club Leicester. The actual gym though, was a classic tiny hotel gym with no barbells to be found. With some improvisation (see below) we could at least get a decent upper-body workout done. In future blog posts, I'm going to keep you updated on how you can get cheap access to gyms & supplements while traveling.

To summarize, I really enjoyed NSConference 6 and will certainly show up next year again. Hopefully, I will meet some of the amazing people again in my travels :)

As I'm writing this, I sit in the Posh Lounge at the Castle Rock Hostel in Edinburgh, enjoying the calmness of Scotland. Since I will be staying here for a while (10 days). I aim to get some coding and writing done. I have quite a list of topics to write about so if everything goes well, there will be posts up both from a technical and a UX perspective. Until then, keep following my journey here and on Twitter & Instagram!