• How To Test UIAlertController in Swift

    Update Nov. 25th 2015: This kind of testing does not work. You can find the correct version here.

    Recently I read a blog post about testing UIAlertController in Objective-C using control swizzling. Posts like this always trigger me to find a way to test the same without the swizzling. I know that swizzling is a powerful tool developers should have access to in their developer tool box. But I personally avoid it when ever I can. In fact only one app I worked on in the last six years used swizzling. And today I believe we could have implemented it without it.

    So how to test UIAlertController in Swift without the swizzling?

    Read more...

  • How To Build An App Without Interface Builder – Part 7: Nicer Cell

    Now let's make the table view cell nicer. First we need a patter image. I used Paintcode to generate this patter:

    cellBackgroundPattern@3x

    You can download the pattern images here. Put the three images into the assed catalog of the app. Now open BirthdayCell.swift and add the following property:

    let patternView: UIView

    In the initializer before the super.init call add the code:

    patternView = UIView()
    patternView.translatesAutoresizingMaskIntoConstraints = false

    This is needed because non optional properties need to be initialized when super.init is called.

    Now set the patter as the background color of the patter view and add the it to the cell by adding the following code after the super.init call:

    patternView.backgroundColor = UIColor(patternImage: UIImage(named: "cellBackgroundPattern")!)
    
    addSubview(patternView)
    
    Read more...

  • How To Build An App Without Interface Builder - Part 6: Show Data

    In part 5 we have seen how we can add birthdays to the app. But the data was just printed to the debug console.

    In this post we want to implement that the birthdays we add are actually shown in the birthday list.

    Open BirthdaysListDataProvider and add the following property:

    private var birthdays = [Birthday]()

    Add the following code outside of the BirthdaysListDataProvider class:

    extension BirthdaysListDataProvider {
      func addBirthday(birthday: Birthday) {
        birthdays.append(birthday)
      }
    }

    Replace the code inside of

    tableView(_:numberOfRowsInSection:)

    with this:

    return birthdays.count
    Read more...

  • How To Build An App Without Interface Builder - Part 5: Data Model

    In part 4 of this series we have implemented the bare bones of the view controller and the data source for the table view. Before we can flesh out those classes, we need a data model to store the data in.

    Let's use a struct for the data model because this is the way to go in Swift. Go to File / New / File... and select an iOS / Source / Swift File. Put in the name Birthday create a new folder called Model and click two times Create. You end up with an empty swift file. Ok, it's not completely empty. There is a comment and it imports Foundation.

    Put in the following struct definition:

    struct Birthday {
        let firstName: String
        let lastName: String
        let birthday: NSDateComponents
    }

    For now this is the complete model implementation. We will later add archiving and unarchiving to this model. But for now it is enough to keep the code flowing. :)

    The app should allow the addition of birthdays of friends and family the user have in their address book. So we need a button somewhere. It is very common in an app showing a table view to have buttons in a navigation bar. To add a navigation bar we will put the view controller into a navigation controller. This has the additional benefit that we can easily navigate to detail views later in the implementation.

    Read more...

  • NSCoding And Swift Structs

    As you all know NSCoding doesn’t work with Swift structs. NSCoding only works for classes inheriting from NSObject. But the next (or current) big thing are structs. Value types all the way. So we need a way to archive and unarchive instances of structs.

    Janie wrote about how they solved it at Sonoplot where she works.

    Tl;dr: They define a protocol that has two methods: one for getting an NSDictionary out of a struct and one for initializing the struct with an NSDictionary. The NSDictionary is then serialized using NSKeyedArchiver. The beauty of this approach is that each struct conforming to that protocol can be serialized.

    I came up with an other approach. It just popped up in my mind. And even after experimenting with it and implementing a little toy project I’m still not sure if this is a good idea. It’s definitely not as beautiful as the approach mentioned above. I put it here to let you decide.

    Read more...

  • How To Build An App Without Interface Builder - Part 4: DataSource

    As mentioned in Part 3 we will proceed this series without using TDD.

    In this part we will add a data source for the table view and we will configure it to show some dummy cell to make sure we have set up everything correctly.

    So, we already have a view controller, BirthdaysListViewController, which is a subclass of UITableViewController. Xcode automatically adds some methods to start with. But we want to start with a blank slate. So delete everything except the following code:

    import UIKit
    
    class BirthdaysListViewController: UITableViewController {
    
    }

    Now let's make sure this view controller is loaded when the app starts. Add the following code within the class BirthdaysListViewController:

    override func viewDidLoad() {
      view.backgroundColor = .redColor()
    }
    Read more...

  • How To Build An App Without Interface Builder - Part 3: A Decision

    I'm sorry. In the first three parts I have a bad copy-paste-error in the title. 'Build' was missing an 'u'. Thanks to @marczobec for pointing it out.

    And over the weekend I made a decision. I will drop the TDD part of this series. I realized that I wanted to much. TDD would just distract from the main topic: Building an app without Interface Builder. Maybe I will show TDD in a later series.

    Part 4: Data Source

    Read more...

  • Where To Put The Auto Layout Code

    Auto Layout is kind of magic. Like a sorcerer you tell the elements where to position and how to behave. You don’t put the elements to those positions yourself. The universe moves them because of your spells. Kind of.

    But when should the spells be spoken? In other words when not using Interface Builder, where should the Auto Layout code go?

    From the documentation of the UIView method updateConstraints:

    Custom views that set up constraints themselves should do so by overriding this method.

    Because of this sentence I always thought Apple asks me to put the layout code in this method. But here is the problem: This method is called more than once by UIKit and adding the same constraint more than once is an error. The suggested approach I found in the Internet™ is to add a boolean to the view class and set it in updateConstraints() to make sure to only run the layout code once.

    Read more...

  • How To Bild An App Without Interface Builder - Part 2: Sketches, Structure, Tests

    This is part 2 of the blog series: How To Build An App Without Interface Builder. You can find information about this series here. In the previous post we set up the project and removed the storyboard.

    In part 2 we will see sketches of the app, we will discuss the structure of the project and we will create our first tests (remember, we try to stick with Test Driven Development (TDD) for this app).

    Sketches

    What should the app look like? I have doodled around a bit and came up with the following sketches (made using Paper by 53):
    IMG_0094

    The main view of the app is going to show a list. In the list are the birthdays of friends and family ordered by time until birthday. In the cells of the list is a progress indicator which color will be selectable in the input of the birthday.

    Read more...

  • Don't Put View Code Into Your View Controller

    Sometimes I see code that sets up subviews in viewDidLoad() of a view controller. Be a good citizen and don’t do that. If you have to add something to a view, do it in a UIView subclass.

    Here is how I implement view and controller code when I’m not using Interface Builder.

    The View

    Let’s build a login view:

    Read more...



subscribe via RSS