Adventures in iOS Development
Unit Testing and Clean Code Exploration Toolbox Archive About Feed

Migrating to Swift 2.0 - It's The Little Things

Wtih Swift 2 now official, it’s good time to give migration from 1.2 a go. It can be longer-than-expected process - automatic updater can only get you so far. Instead of whining about it, I’ll go over some of the smaller features that don’t get as much spotlight as others.

Read more

LLDB Tips

Three tips that make debugging easier.

Step faster

Stepping over/into in the debugger can be really slow. Turns out that Debug navigator is the main culprit here. If it gets slow just hide navigator pane (⌘+0) or change to different navigator and enjoy full speed 1.

Read more

My WWDC 2015 Wishlist

WWDC is about to start in 9 hours. Here’s my modest wishlist:

  • stable tools and iOS - I know, boring,
  • nice refactoring tools in Xcode - if open source Flashdevelop can do it, Apple can do it!
  • extensions to Swift language:
  • Result enum - everybody have been blogging and talking about it for the last year, plus Rust has it,
  • await and async keywords - we are closely catching up on JavaScript’s 10+ different ways of doing async stuff. It’s such a big part of our work, that support for it should be baked into the language/compiler. See how nice it is in C#:
  public partial class MainWindow : Window
  {
    // Mark the event handler with async so you can use await in it. 
    private async void StartButton_Click(object sender, RoutedEventArgs e)
    {
        // Call and await separately. 
        //Task<int> getLengthTask = AccessTheWebAsync(); 
        //// You can do independent work here. 
        //int contentLength = await getLengthTask; 

        int contentLength = await AccessTheWebAsync();

        resultsTextBox.Text +=
            String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
    }


    // Three things to note in the signature: 
    //  - The method has an async modifier.  
    //  - The return type is Task or Task<T>. (See "Return Types" section.)
    //    Here, it is Task<int> because the return statement returns an integer. 
    //  - The method name ends in "Async."
    async Task<int> AccessTheWebAsync()
    { 
        // You need to add a reference to System.Net.Http to declare client.
        HttpClient client = new HttpClient();

        // GetStringAsync returns a Task<string>. That means that when you await the 
        // task you'll get a string (urlContents).
        Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

        // You can do work here that doesn't rely on the string from GetStringAsync.
        DoIndependentWork();

        // The await operator suspends AccessTheWebAsync. 
        //  - AccessTheWebAsync can't continue until getStringTask is complete. 
        //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
        //  - Control resumes here when getStringTask is complete.  
        //  - The await operator then retrieves the string result from getStringTask. 
        string urlContents = await getStringTask;

        // The return statement specifies an integer result. 
        // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
        return urlContents.Length;
    }

    void DoIndependentWork()
    {
        resultsTextBox.Text += "Working . . . . . . .\r\n";
    }
}

List may be short, but those features are essential and would make our life easier. With them in place we could place more focus on solving interesting problems.

CocoaPods tools, tips & tricks

In the spirit of Ash Furrow’s Teaching & Learning, here’s a compilation of CocoaPods pointers I’ve picked up after maintaining private pods daily.

Using private spec repo

It’s something to consider, even if you don’t maintain private pods, in the following situations:

  • using bleeding edge version of the library, that isn’t deemed stable yet (not tagged, no podspec for this version yet),
  • there’s a bug fix that you just need, but fix isn’t in version referenced in a podspec and maintainers don’t want to update patch version,
  • having fork with functionality you specifically need/maintainer not appreciating the pull request.

And the usual use cases for this:

  • maintaining private library (you can get by using :git, however…),
  • private library having dependency on another private library.
Read more

NSErrorPointerWrapper: Simplified handling of Cocoa Touch API errors in Swift

The Pod source is here: NSErrorPointerWrapper. Read further for motivations and short overview.

Dealing with NSError in Objective-C is clunky at best. You have to create a variable of *NSError type, then pass it by reference to the potentially erroneous method. That variable may or may not be populated as a result of an action. In fact it’s recommended to check the result, not the error, to verify whether the action was successful.

Read more