Apple Music: Should I Stay or Should I Go?

So there’s been some negative things written about Apple Music over the last three months. And there have been a bunch of bugs (you can read about them here, here or here or just experience them yourself, they are there). But today is the day when push comes to shove and all of us that joined on day 1 need to decide if we’re staying or not. I’ve been thinking about it and I’m staying. And this is because I like it.

Really, I do.

Now, maybe I’m not enough of a Music-Tech power buyer. My iTunes library only consists of nineteen point five days of music (7,500ish tracks). Is that a lot? I really don’t know, I just pick through it and listen to an album here and there depending on the kind of music I’d like to hear. A portion of it came from college days of trading around albums or individual tracks. The rest came from rips of physical media my wife and I have owned or, in the past 10 years, purchased from iTMS (remember the days when it was just a music store?) or Amazon music.

There are a few of different things I like to do when listening to music. The first is pretty universal, it’s that thing where you think of an album or song and then you want to listen to it. Streaming services are great for this since you can just go and listen to anything in the catalog. And, unless you own every song that you’ll ever want to play, you’ll need to buy it or go hunting on YouTube, Free Spotify, etc. Apple Music has the largest and best catalog of any service out there so it does well on this one. I myself don’t own anywhere near the full discography for all the artists I like, so a subscription service is great and Apple’s works across all my devices (unlikely Spotify or YouTube).

The second thing I love is finding a great new band or album that I didn’t know about before. There is roughly speaking an infinite amount of music in the world. Given this fact, there is the distinct possibility that you and I haven’t actually found our favorite music yet (if you take into account the musical taste imprinting that happens as a young adult this might not be true, but from a purely statistics viewpoint it holds up pretty well). Apple blows the competition out of the water on this. Between curated playlists that are pushed into the “For You” feed, crosslinking between similar artists and a seemingly decent search feature (definitely better than Spotify’s… or the App Store’s for that matter), I’ve enjoyed finding new interesting music more than ever before. To bring this down to earth, here’s a selection of some of the albums I discovered this past week: - Trans Europe Express / Kraftwerk (Never really listened to anything other than the mega hits in the past.) - Beauty Behind the Madness / The Weeknd (Hey, it’s worth a try even though I’m not much for pop right? Nope.) - Music in Exile / Songhoy Blues. (Super awesome, go take a listen) - Teen Dream / Beach House - Khun Narin’s Electric Phin Band / Khun Narin - Break Mirrors / Blake Mills This is simply phenomenal. I suggest you go do the same.

With these two big ones out of the way here are some more things that I love:

  • For you. Sure it gets it wrong that I like Katy Perry. But that’s likely just Apple’s pop-leaning wishful thinking. There’s a way to mark recommendations as crap, and listen to me, you don’t have to do every single thing anyone recommends that you do. I serious. And guess what, I do love The Lips, Pavement, Uncle Tupelo, and boy was I into Coldplay in the early 2000s.
  • Up Next on iOS. The best. I have waited for this for oh so many years. You could delete all my purchased music twice as long as you just let me queue up the next seven tracks while I sit at a particularly long red light. Even better, telling Siri “Play The Final Countdown next” works exactly as it should.
  • Beats 1. Know the last time I listened to an actual radio show on purpose? Never. Seriously, before St. Vincent’s Mixtape Delivery Service I had quite literally never specifically tuned in to catch a radio show.

Now if I had am enormous music library that I was happy with and never wanted to listen to anything new, would I like Apple Music? Quite possibly not. My feeling with music is that if I ever catch myself solely listening to the stuff I liked when I was X years old (where X < my current age), I’ve stopped really enjoying music. This is just for me personally, and I don’t anyone else to do the same. But I came to this conclusion because I did just this for a couple years once. What I came to realize was that I stopped being able to really talk with people about music or enjoy much music that wasn’t my own. In fact, at some point I just stopped listening to music as a normal part of day to day life and I think this was because it was less interesting than it once was.

So I’ll keep my Apple Music subscription and keep exploring old and new music and listening to the music that I know and love. All at the same time.

MusicApple

Storing Key-Value Data in iCloud with Swift

Kristen

Hi, I’m Kristen––an iOS development newbie and Nice Mohawk’s summer intern. Most recently, Ben assigned me the task of building a simple example app that uses iCloud to store key-value data.

As one would expect, I immediately looked for a tutorial on the subject. I was disappointed, however, to come up short: all of the tutorials I found were written in Objective-C and I––the newbie who only knows Swift––could only half understand what was going on.

Thankfully, I did eventually figure out how to do all of this in Swift. It wasn’t too bad, either.

I decided to build an app with a text field and button, so that a user can type a short message and save it to iCloud. I began by setting up iCloud entitlements (see steps 1 & 2).

I then opened my ViewController.swift file and declared and initialized an NSUbiquitousKeyValueStore object:

var iCloudKeyStore: NSUbiquitousKeyValueStore? = NSUbiquitousKeyValueStore()

The NSUbiquitousKeyValueStore class allows you to save values of various types––NSNumber, NSString, NSDictionary, etc.––and associate them with a key. To save the user’s message for my app, I created an outlet for my text field and a function to call the setString:forKey and synchronize methods. setString:forKey: pairs the text field’s contents with a key, while synchronize saves the message to iCloud.

let iCloudTextKey = “iCloudText”
@IBOutlet weak var textField: UITextField!  

…

func saveToiCloud() {
    iCloudKeyStore?.setString(textField.text, forKey: iCloudTextKey)
    iCloudKeyStore?.synchronize()
}

I later realized that I should display the last message the user saved upon launching the app. To do this, I made a function that uses optional chaining and the stringForKey: method to check for and display a previously saved message.

func iCloudSetUp() {
    if let savedString = iCloudKeyStore?.stringForKey(iCloudTextKey) {
        textField.text = savedString
    }
}

Within the same function, I also registered for the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification so that my app could handle any changes made to the text field by other instances of the app while running.

✍ Ben: Sorry if you’re reading this on a phone screen. Some bits were overlooked in Cocoa’s conversion to Swift and haven’t transitioned as completely as others. Notification constant names are one where you can tell they didn’t get any love from Swift’s move toward more concise descriptors.

Using the addObserver method to do this also requires an additional function to take some sort of action. In my case, I made this function update the message in the text field.

func iCloudSetUp() {
    …
    NSNotificationCenter.defaultCenter().addObserver(self,
    	selector: “ubiquitousKeyValueStoreDidChangeExternally:",
    	name:  NSUbiquitousKeyValueStoreDidChangeExternallyNotification,
    	object: iCloudKeyStore)
}

func ubiquitousKeyValueStoreDidChangeExternally() {
    textField.text = iCloudKeyStore?.stringForKey(iCloudTextKey)
}

Here’s the finished project repository on GitHub. Note that the program is slightly more complicated, as I decided to incorporate a switch that allows the user to save text locally using NSUserDefaults or to iCloud.

And that’s it! Not too bad, right?

✍ Kristen is pursuing a CS degree at Ohio University and recently finished her freshman year. This summer she’s working on learning mobile development with Swift and updating Nice Mohawk apps built with Swift, namely TypeSnippets.

SwifttutorialiCloud

Ben on App Masters Podcast

Ben

A few weeks ago I had the opportunity to have a chat with Steve Young from AppMasters.co and my recent partner in crime (and long time friend), Joshua Keay. Joshua has recently been working from Saigon, Vietnam. Steve is in California and I’m in Ohio. Despite that mix of time zones and internet quality, we had an enjoyable discussion centered around our recent launch of PhoneExpander. I think the most interesting topic we got to cover was the challenge of making apps that fill a user’s need instead of simply filling a want. This is an interesting concept and kudos to Joshua for unpacking it nicely.

The Podcast episode is now live. Go give it a listen for youself!

App Masters Episode #279.

PodcastsIndieApps

PhoneExpander

ATHENS, Ohio—February 3, 2015—Nice Mohawk Limited announces the public beta release of PhoneExpander, a Mac app to help you free up space on your iOS devices.

PhoneExpander

With iOS 8, apps and photos taking up more space than ever, it’s very easy for users to fill up their devices. Many users deal with storage limitations on a daily basis and almost all users have received a “Not Enough Storage” or “Storage Almost Full” warning at some point. Five minutes of running PhoneExpander can free up gigabytes of previously unusable space. PhoneExpander consists of a set of tools, each focused on clearing out a different kind of data on a users’ devices. For example, when inspecting an iPhone in iTunes, a large amount of storage space is simply labeled as “Other” — this data is usually a combination of old media and cache files stored by applications. Media heavy apps like Facebook, Spotify and Vine can store hundreds of megabytes, or in some cases even gigabytes, of cached data apiece, but there is no way to clear that cached data except to delete and reinstall the application. PhoneExpander can clear these caches with the click of a button. Additionally, PhoneExpander offers easy ways to backup and remove space hogging pictures and videos, batch delete large apps and, in the future, will offer control over the music stored on the device. Created in response to users’ inability to install iOS 8 on their devices due to constrained storage space.

Developed in collaboration with Magnetism Studios, PhoneExpander 1.0 will be introduced in Spring 2015 and will include additional space saving tools.

PhoneExpander public beta is available at PhoneExpander.com.

MaciOSPhoneExpander

Adding forEach() to Swift Arrays

Ben

I’ve been working on a small project in Swift recently. It’s been both fun and amazingly frustrating at turns. Moving from a language which I’ve been using for 13+ years to one that I’ve only known about for 3 months is hard.

One of the things I’m not used to yet is a base object set that isn’t as full featured as Foundation’s. This isn’t a nock against Swift, just an obvious difference that I think will change with time. Swift has also been built such that it’s quite a bit easier and more acceptable to add basic functionality to these standard library types. However, for me always remembering that I can do this is the trick.

Today I was wanting the functionality provided by NSArray’s
-makeObjectsPerformSelector: method. I could have just briged the Swift array I was working with into an NSArray and called the method, but I felt like it might be nice to try extending Array instead. This is what I came up with:

extension Array {
	func forEach(doThis: (element: T) -> Void) {
		for e in self {
			doThis(element: e)
		}
	}
}

Wow. That was easy! Code to use it simply looks like:

someArray.forEach { element in 
	// do something with the element
}

Being able to make this kind of simple extension to a low level type and having it just work makes me a little more open to the idea of Generics invading our little corner of the software development world.

SwiftCode

Ita 2.0 as a Case Study for List App Design

Ben

Last week we released a big update to our list-making app, Ita. For version 2.0 we redesigned the look of the app, but we also changed some of the interactions to create an even more simple and consistent interface throughout the app. Ita’s goal has always been to be the most quick, simple and enjoyable list making app out there, so we thought we’d talk a bit about how we designed Ita’s interaction model and compare it to some other list apps out there.

Bob

Ita 2.0 has a new feature called “edit mode” that lets users switch between editing items without having to go back to the normal list view (just tap another item!) like you did in Ita 1.x. We like this feature, and it changed user interaction within a list in a variety of ways. When designing that feature, it was helpful to look closely at different apps and see how they handled similar problems. With that type of process in mind, it seems useful to think through the different things that you can do with a list, and look at how a few popular list apps respond to similar challenges. Users need to do a core set of things with their lists: create new items, edit item text, reorder items, mark items completed/uncompleted, and delete items. It’s hard to make all of these options available to the user at any given point. So list apps have to prioritize some actions over others while preserving design space for any unique features of their own.
 

The System Standard: Reminders

✍ Ben: Wait, isn’t the system standard Notes.app?

✍ Bob: Notes isn’t a list app?

✍ Ben: But so many people use it to make lists! We all know they’re doing it wrong, but…

✍ Bob: Good point. 1) They should use Ita. 2) While you can use a text editor to make lists (I do it all the time on my Mac), it’s easier to make a list on iOS using a dedicated list app than a text editor for various reasons we should avoid going into now. Dedicated list apps generally share user interface patterns that make comparing them to each other both more informative than and very different from comparing text editors. So let’s call Reminders “The System Standard List App.”

The System Standard List App: Notes Reminders

  • Create new items:
    When not editing, tap anywhere at the bottom of the list. While editing an item, tap only on the single empty line immediately after the last item on the list.
  • Edit item text:
    Tap on an item. Only available when not in “global editing” mode (“global editing” mode is accessed by tapping the “edit” button which is visible when not editing an item).
  • Reorder items:
    Reordering is only available in “global editing” mode.
  • Mark items completed:
    Tap the dot next to item text in left-hand margin. Available while editing an item for all items except the one being edited. Not available in “global editing” mode.
  • Delete items:
    Swipe on an item, then tap delete button; also available in “global editing” mode, where pressing the delete button has the same result as a swipe (and gives you the “more” option!? Understandable, but not a super elegant bit of UI —Bob).
  • Additional Functions:
    Reminders has a “More” button that allows one to add recurrence or date/time alerts to an item. This is available by pressing the detail disclosure button while editing an item (which is a really neat bit of UI) or by swiping left on an item and tapping “more.”

 

A Custom Gesture-Based Interface: Clear

  • Create new items:
    Pull down on list or pinch into list.
  • Edit item text:
    Tap an item.
  • Reorder items:
    Long press an item, then drag to new location
  • Mark items completed/uncompleted:
    Swipe to the right.
  • Delete items:
    Swipe to the left
  • Additional Functions:
    Shake to undo. Can add reminders to items.

✍ Bob: While this interface is much more simple than that of Reminders.app, neither of us can use Clear without becoming wildly frustrated within seconds. But for people with whom it “clicks,” they really like it.

 

The Common Denominator (comes with an extra kitchen sink): Wunderlist

  • Create new items:
    Tap the “Add an item…” box at the top of the list.
  • Edit item text:
    Tap an item to open it, then tap the text box on the resulting screen. Or swipe to the left, then tap the pencil icon.
  • Reorder items:
    Long press, then drag to new location. Or tap the “Sort” button at the bottom of the screen and then choose a sorting option.
  • Mark items completed/uncompleted:
    Tap the checkbox next to an item.
  • Delete items:
    Swipe left, tap the trash can, then tap “Delete item” to confirm. Alternatively, tap an item, then tap the three-vertical-dot-button at the bottom-right, then tap the trash can, then tap “Delete” to confirm.
  • Additional Functions:
    Lots of other functions in the toolbar at the bottom of the screen or the “Share” button at the top right corner of screen or you can pull down to initiate sync.

 

You’ve Tried the Rest, Now Try the Best: Ita

  • Create new items:
    Tap the plus button.
  • Edit item text:
    Tap the edit hand button to to enter “edit” mode. Or to starting editing a specific item, swipe left on that item, then tap the edit hand. Tapping on any item when editing or adding items switches to editing that item.
  • Reorder items:
    Long press an item, then drag to new location. Not available while editing/adding items.
  • Mark items completed/uncompleted:
    Tap an item. To combat accidental marking we wait a moment for a second tap which reverts the items to it prior state. Not available while editing/adding items
  • Delete items:
    Swipe to the left, then tap the trash can.
  • Additional Functions:
    Action button at bottom of list allows sharing, removing completed items, restoring completed items to their uncompleted state, renaming list title, deleting list.

Ben

What we can see is that each app has an opinion about which actions are most important. For Reminders, this is editing an item (it only takes one tap) followed by creating new reminders (I’m not completely sure about this actually since it gets murky quick). With Clear, it is obviously creating new items that is most easily accessible at any given moment. Wunderlist has an abundance of features, none of which standout as a primary focus but as a whole make the app very full featured.

With Ita, we’ve focused on the act of marking items complete (a single tap) and reordering items (a long press). This is because when you are using a list, these are the actions that you do most often. (ex: You bought a present off your list of gift ideas, picked up a new record from your recommended music list, or you moved a task lower down on your daily todo list).

In addition to our assumed common uses of lists, there are those other things that you do with a list. We treat these as quantified interactions that can be split off from the most common use of an existing list. Adding items is something that users do all the time, but they often do it several times in a row (perhaps mixed with editing some items as well), so that mode can be accessed via a single targeted tap on the plus button. Editing is done either to a single item or to multiple items in series but occurs less frequently than creating items, marking them completed or reordering. Because of this, while it can also be accessed via avery simple action, that action is given less prime real estate.

Bob

I hope we’ve done an OK job of documenting how these other apps work; we’re not in a position to know much about the motivations of those other developers or know why/how they’ve made design decisions.

✍ Ben: And while we don’t want to pan any of them particularly, we think any discerning list maker will most certainly see how nice Ita is.

What we can share are some of the principles we use when making design decisions, apart from the specifics of the feature we’re designing.

  • Know Your Audience. We want Ita to be useful for casual users and, just as importantly, for power users who are distracted. Ita’s not OmniFocus; it’s not even as complicated as Reminders. We want to create a place for lists that can be checked off while you’re packing or at the store (Ita’s average session length is less than 30 seconds per use). Simplicity isn’t just for casual users; simplicity is also about providing a clear experience for users who might need to focus on stuff other than our app.

  • Leave Room to Grow. We have a current feature set that we’re happy with, but we’re also planning for future releases. We want to leave space for adding features to the app. If we make the app as complicated as it can comfortably be, then adding new features will make the app feel cramped or require a redesign that will take development resources and require reeducating users. (And those reeducation camps are expensive.)

  • Be Like Apple. We want to follow standard iOS conventions all the time, unless we have a good reason not to. Yes, part of that means reading the HIG. The other part is looking closely at user interaction in stock apps and trying to understand how and why they work the way they do. Mail and Reminders are great examples for us — Mail in particular is usually on the cutting edge of Apple’s public UI innovations.

Ben

If you haven’t already used Ita 2.0, go get it. We’re really happy with the interactions and the new features, but we like to hear feedback on our design choices. Tweet us @nicemohawk and we can have a conversation 140 characters at a time.

ItaUser InteractionDesignLists