How to add navigation items to the Navigation Bar iOS

Leave a comment

When you embed your root viewController into a NavigationController, your sub ViewControllers automatically get a title bar. But they don’t get any Nav bar items.

Screen Shot 2018-07-16 at 6.45.06 AM.png

To add something like a Welcome button for back navigation drag out a Navigation Item

Screen Shot 2018-07-16 at 6.45.26 AM.png

And drop it into the middle of the navbar. Same for a button. Only a NavBar button is different than a Navigation item. It looks like this.

Screen Shot 2018-07-16 at 6.45.31 AM.png

Drag this to the upper right hand corner of the nav bar and it should be OK.

Advertisements

How to change which ViewController loads at startup in Storyboard

Leave a comment

You can drag around the little arrow from one VC to the other. Or your can select the little checkbox in the menu titled ‘Is Initial View Controller’ near the top on the right hand side.

Screen Shot 2018-07-16 at 6.36.46 AM.png

When to use Optionals in Swift

Leave a comment

Being new to Optionals, sometimes I struggle for good examples on where and when to use them.

Here’s an example I link that show how one could use an Optional to model an AccountBalance.

struct AccountBalance {
    init(_ ledger: Money, overdraftLimit: Money? = nil) {
        self.ledger = ledger
        self.overdraftLimit = overdraftLimit
    }

    var available: Money {
        if let overdraftLimit = overdraftLimit {
            return ledger + overdraftLimit
        }
        return ledger
    }

    let ledger: Money
    let overdraftLimit: Money?
}

Both the ledger and overdraftLimit are let’s (meaning once assigned they can’t be changed). But the overdraftLimit is also an Optional because the overdraftLimit may or may not exist for this account.

I like this example because it shows how the overdraftLimit exists for some but not others. It truly is Optional. And for those who don’t have it we need some kind of check.

Building on that, here are the methods to increase/decrease the amounts of funds.

func increased(by amount: Money) -> AccountBalance {
    return AccountBalance(ledger + amount, overdraftLimit: overdraftLimit)
}

func decreased(by amount: Money) -> AccountBalance? {
    guard amount <= available else { return nil }
    return AccountBalance(ledger - amount, overdraftLimit: overdraftLimit)
}

Notice here how the AccountBalance in decreasedBy is also an Optional? This is because this operation could fail if the account does not have sufficient funds. This is a really good example of how to use a guard clause to see if something bad might happen, and then instead of throwing an error (i.e. InSufficientFunds) instead simply returning a nil when the client can guard and look for (which we will see in the next step).

We can bring it all together like this.

class Account {
init(identifier: AccountIdentifier, balance: AccountBalance) {
self.identifier = identifier
self.balance = balance
}

func credit(_ amount: Money) {
balance = balance.increased(by: amount)
}

func debit(_ amount: Money) throws {
guard let newBalance = balance.decreased(by: amount) else {
throw AccountError.insufficientBalance
}
balance = newBalance
}

let identifier: AccountIdentifier
private(set) var balance: AccountBalance
}

enum AccountError: Error {
case insufficientBalance
}

Here we can see how:

  • The AccountIdentifer can be a let, but a let that dynamically builds itself based on internal properties
  • The AccountBalance is a private(set) meaning no one can change its value save the AccountBalance itself
  • The AccountBalance continuously creates new instances of itself, always representing itself as a Value object (safer than a reference)
  • The debit method looks for that Optional if anything goes bad (much nicer than having to try catch and error). Here is simply looks for the nil (or Optional) being returned by protects itself with a guard clause at which point it decides to throw an Error

Really nice example showing a lot of the different constructs and how to use them in Swift.

Thanks to Khawer Khaliq for this great example.

How to add a custom UITableViewCell Swift

Leave a comment

Create a new UITableViewCell in Swift (with nib)

Screen Shot 2018-06-24 at 7.56.16 AM.png

Give it a unique identifier

Screen Shot 2018-06-24 at 7.57.14 AM.png

Load it up in your ViewController

Screen Shot 2018-06-24 at 7.58.01 AM.png

Then access it in your UITableView delegate methods like this

Screen Shot 2018-06-24 at 8.02.41 AM.png

Screen Shot 2018-06-24 at 8.02.47 AM.png

Give your cell a default height in the ViewController else you will get a warning

Screen Shot 2018-06-24 at 8.15.48 AM.png

How to hookup UITableView Swift

Leave a comment

Screen Shot 2018-06-24 at 7.37.39 AM.png

Implement the protocols, get a reference to the tableView in the VC, and set yourself as the x2 delegates.

Then implement these x2 methodsScreen Shot 2018-06-24 at 7.38.50 AM.png

Give your prototype cell a reuse identifier

Screen Shot 2018-06-24 at 8.10.14 AM.png

Launching iMessage on Spotify

1 Comment

This week, a project me and my friends here in San Francisco have been working on finally went live. The Spotify iMessage App Extension.

Screen Shot 2017-08-04 at 1.25.07 PM.png

This app extension let’s you search for songs, send them to friends, and then play short 30 sec clips.

Sep-15-2017 08-14-06.gif

I know it doesn’t look like much – but it was a lot of work! You’ve got just the basic functionality of the App itself. You’ve got error handling. How to handle going off line. Analytics. Authorization. The expand and collapse interaction of iMessage. Nasty bugs. And the requirement to support both portrait and landscape orientations too (thank you UIStackView).

Sep-15-2017 08-18-08.gif

You don’t launch something like this without a lot of help. And I want to thank:

And my partner in crime, with whom this all started as a Spotify hackweek project, Joseph Baena.

Without them none of this would have worked.
So thank you team.
Onwards and upwards.
Looking forward to iterating more on this great platform!

Oh. And we are hiring! So if you are a mobile iOS or Android engineer, and have always wanted to work a great team in the great San Francisco Bay area, go checkout our job listings here and see if you’d like to join the band.

Links

How to keep you tests non-flakey

1 Comment

Something I am always striving to avoid in my unit tests is flakiness. That’s why when I needed to deal with a UINavigation bar in the previous version of iMessage, I ended up writing a method that looked like this:

Screen Shot 2017-09-13 at 10.19.35 AM.png

This method puts the responsibility on the client to figure out the runtime of the device, so this method is relatively straight forward and doesn’t suffer from any of the shenanigans that come with embedding lines of code like this, in classes you want to test.

Screen Shot 2017-09-13 at 10.25.54 AM.png

The power of overriding – or always asking for more

A colleague and I in a code review where debating the merits of this approach. The ugliness of exposing these details versus the desire to keep the code clean and testable. Together we came upon the following solution.

Make a public API that is easy and another one that is testable. Then have the public API call the more testable one

So that’s what we did.

Screen Shot 2017-09-13 at 10.30.17 AM.png

The lesson for me here is to always remember you can do anything with software. Got an interface you don’t like? Create a new one. Software is the one disciple where you can have your cake and eat it to. Just create whatever you need, and implement behind the scenes however your like.

Older Entries

%d bloggers like this: