Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SeatGeek's iMessage App at iOSoho on 13 Feb 2017

SeatGeek's iMessage App at iOSoho on 13 Feb 2017

SeatGeek’s iMessage App takes the most social parts of the product and makes them available within the iOS Messages app. Users can search for events to discuss with their friends, and then send the tickets quickly and easily without the hassle of PDFs or printing. The app was written in Objective-C for a tight deadline, and you’ll hear about how we simplified existing features to optimize for both real-world usefulness and minimal development effort.

Steven started developing for iOS in 2009 and – after forays into Javascript in the browser, Python for chat bots, and Chef on AWS – returned to it in 2014. He studied offline spaces at Stanford's architecture program and online spaces at NYU's Interactive Telecommunications Program, and now helps people attend more live events at SeatGeek.

Video: https://drive.google.com/file/d/0B-qtOJ9Zixp3LWNveVp3OWxlTXc/view

Event: https://www.meetup.com/iOSoho/events/233423358/

Blog post: http://chairnerd.seatgeek.com/see-more-events-together-with-the-new-seatgeek-imessage-app/

App: https://itunes.apple.com/us/app/seatgeek-tickets-to-sports/id582790430

Job listing: https://seatgeek.com/jobs/ios_engineer

Steven Lehrburger

February 13, 2017
Tweet

Other Decks in Technology

Transcript

  1. iMessage App SeatGeek SeatGeek’s Steven Lehrburger – iOSoho on February

    13, 2017 [email protected] – twitter.com/lehrblogger Hi everyone, thanks for coming to the SeatGeek office. My name is Steven Lehrburger, and I’m one of the iOS Engineers here. This evening’s talk is about our iMessage app. ----- Video: https://drive.google.com/file/d/0B-qtOJ9Zixp3LWNveVp3OWxlTXc/view Event: https://www.meetup.com/iOSoho/events/233423358/ Blog post: http://chairnerd.seatgeek.com/see-more-events-together-with-the-new-seatgeek-imessage-app/ App: https://itunes.apple.com/us/app/seatgeek-tickets-to-sports/id582790430 Job listing: https://seatgeek.com/jobs/ios_engineer
  2. @ What is SeatGeek? • A mobile-focused event ticketing company

    • We make it easier for people to see their favorite teams, bands, and shows What do we do here? SeatGeek is a mobile-focused event ticketing company. We believe that live events offer uniquely meaningful experiences, so we want to make it easier for people to see their favorite teams, bands, and shows.
  3. This slide usually goes at the end, but none of

    this would have happened without these people: James, who works with me on the iOS app, lives in London. He did the vast majority of the work on the iMessage app, but couldn’t be here to present. Zack, who helped us out with some API changes, is here in New York. Mladen did the designs, and is in The Netherlands. And last but not least, Adam was the product manager, also here in New York. @ Acknowledgements James Vanas iOS Engineer London Zack Kitzmiller API Engineer New York Mladen Zivanovic Product Designer The Netherlands Adam Waxman Product Manager New York
  4. A note on terminology. Is the word “iMessage” or “Messages”?

    .. Yes. As best I understand it: We made an iMessage app Which lives within the Messages app on iOS (Which is distinct from the Messages app on macOS) Which is built with the Messages framework … Which uses the MS class prefix, not IM or iM, so maybe that’s why things are name what they are? @ Messages or iMessage? • We made an iMessage app • Which lives within the Messages app on iOS • (Which is distinct from the Messages app on macOS) • Which is built with the Messages framework • … Which uses the MS class prefix, not IM or iM
  5. Installing these is not exactly intuitive. If any of you

    haven’t tried yet, or haven’t read instructions in the release notes of other apps, This is what you should do: @ @ Messages in iMessage • Installing an iMessage app in Messages 1. Open a conversation
  6. Which does not actually open the App Store, yet. @

    @ Messages in iMessage • Installing an iMessage app in Messages 1. Open a conversation 2. Tap the App Store button
  7. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store
  8. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store 4. Tap the Search icon
  9. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store 4. Tap the Search icon 5. Type in “seatgeek”
  10. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store 4. Tap the Search icon 5. Type in “seatgeek” 6. Tap to download
  11. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store 4. Tap the Search icon 5. Type in “seatgeek” 6. Tap to download 7. Wait
  12. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store 4. Tap the Search icon 5. Type in “seatgeek” 6. Tap to download 7. Wait 8. Close out of everything
  13. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store 4. Tap the Search icon 5. Type in “seatgeek” 6. Tap to download 7. Wait 8. Close out of everything 9. Launch the app
  14. @ @ Messages in iMessage • Installing an iMessage app

    in Messages 1. Open a conversation 2. Tap the App Store button 3. Open the App Store 4. Tap the Search icon 5. Type in “seatgeek” 6. Tap to download 7. Wait 8. Close out of everything 9. Launch the app
  15. The story of SeatGeek’s iMessage App starts at last year’s

    WWDC. Apple announced several changes to Messages, including sticker apps, and the new Messages framework for building richer experiences. In the past we’ve had success earning App Store features by being early adopters of new things in iOS, such as Apple Pay and Spotlight. We wanted to the same thing with an iMessage app, but we had a few other higher-priority projects to finish so couldn’t start until August. So this presentation is about building something as quickly as possible. This helped us simplify, simplify, simplify. Which is important because the interface is even more space-constrained than with a normal app. It was a useful exercise in minimalism - to provide the simplest experience possible given the space constraints. @ @
  16. This project was made much easier by work we had

    done for other extensions. We have a collection of local CocoaPods with code for: Our API requests and models, login state sharing, KVO wrappers, analytics, and other utilities, Which makes it easy to share code between out main app and our Today Widget, Notification Extensions, and experimental Watch App. While keeping our dependency tree clean and managed relatively automatically. @ App Extensions • Local CocoaPods for: • API requests and models • Login state sharing • KVO wrappers • Analytics • Our extensions: • Today Widget • Notification Service and Content Extensions • Watch App (experimental)
  17. We started off with sending tickets. While it’s not the

    first thing that happens in the process, i.e. a user needs to own tickets to the event before she can send them, It fit most naturally with the concept of sending messages to someone in Messages. It’s a fun problem to figure out how to send tickets to a friend in the simplest and most obvious way possible. In the main app, we have to choose a recipient, and then select a quantity if there’s multiple tickets, And then if we set a price, we have to have a way to get paid, like Venmo or a bank account. That’s much too complicated for iMessage, so we had to simplify. I’ll talk about how receiving the ticket works later. @ @ Sending a Ticket • A feature from the main app • Select a ticket • Then a recipient • Then a quantity • Then a price • A natural fit for Messages • Select a ticket • (Receiving will be later)
  18. This is the method that gets called when the user

    taps on one of their ticket cells. We use the word “transfers” internally to refer to sent tickets. It constructs a transfer object, and that `performAction` method makes the API request. There are two things I want to talk about specifically here: @ Sending a Ticket
  19. The first is the recipient UUID, which we get from

    the MSMessagesAppViewController. (Note that sending tickets doesn’t work in group conversations, to keep things simple.) @ Sending a Ticket
  20. The second, which I’ll get back to later, is that

    URL, Which gets set on the `MSMessage` object later on in `createSendMessageFrom`. @ Sending a Ticket
  21. What do we know about the recipients? In iMessage Apps,

    we just have a UUID for each participant. We don’t know the iMessage email address or phone number, Which are recipient types we already supported for sending tickets, But instead we only have an anonymous UUID. While this makes sense as a design decision from Apple to respect the privacy of users with contacts who might install unsavory apps, The restriction required we add API support for sending tickets without specifying a recipient. (I thought we had an icon for that grey circle, for anonymous recipients? I’ll go back and add one…) @ @ Anonymous Recipients • What do we know about the recipients? • No email address or phone number • UUID from MSMessagesAppViewController’s activeConversation. remoteParticipantIdentifiers • Required API support for sending tickets without specifying a recipient
  22. The Message framework recommends you use the URL properly to

    encode data from your app. So, then what is actually being sent, as the URL on the MSMessage? This is the URL we saw a couple slides ago before. https://seatgeek.com/e/transfers/:id/:signature With a signature that allows the visitor to that URL to accept the transfer, Because we can’t otherwise verify who they are. We don’t actually use the UUID for anything. @ @ Anonymous Recipients • What is actually being sent? • https://seatgeek.com/e/transfers/:id/:signature
  23. Why that URL? We ultimately want to launch the main

    SeatGeek app so the user can see the tickets they just received. We initially tried URLs with our own seatgeek colon slash slash protocol, like the ones here. But in iOS 10 beta 5, this suddenly stopped working and just printed an error message. [Default] openURL: failed: <private> We learned from someone at Apple on the developer forums that this was a new, intentional security behavior. It seemed odd that a MSMessage in an iMessage app can’t launch it’s own primary app, but there wasn’t much we could do at the time. @ Recipient URL handling • Why that URL? • We initially tried URLs with our own protocol • seatgeek://transfers/:id/:signature • In iOS 10 beta 5, this stopped opening our app, but we learned on the developer forums that this was a new security behavior…
  24. So, what could we do instead? We investigated Universal Links

    as an alternative. Those are the http colon slash slash links at the Internet domain that we can specify in an entitlement. And then support by hosting an App Site Association file on that domain, in our case, seatgeek. com. That contains regular expressions that specify the URLs that we want to open in the app. All other URLs will open as expected in Safari. Here, we have an entity link for Transfers (in addition to those for events, performers, venues, and so on). They looked uglier for users on older versions of iOS, but we decided to keep moving. We kept both message types in the code in case Apple reversed their decision. @ Recipient URL handling • What can we do instead? Universal links! • https://seatgeek.com/e/transfers/:id/:signature • Add /e/transfers/* to our apple-app-site-association file
  25. In the next beta, deep links to our app started

    working again, although somewhat inconsistently. We figured out we could launch the app using it’s custom protocol, but not Universal Links. So, what ended up working was: If the recipient’s device supports iMessage apps, and has the app installed, Then we can translate the Universal Link into a deep link, and then open the app. @ Recipient URL handling • The solution: • If the recipients device supports iMessage Apps • If the recipient has the app installed • Translate the Universal Link into a deep link, and open the app
  26. Otherwise, if the user doesn’t already have the app, then

    iOS will now magically open the iMessage App Store. Although this is itself a new behavior… Previously, if the app wasn’t installed then it would open Safari and the user could accept the tickets on our mobile website, Which was a reasonable fallback. @ Recipient URL handling • The solution: • If the recipients device supports iMessage Apps • If the recipient has the app installed • Translate the Universal Link into a deep link, and open the app • Else • Open the iMessage App Store with (new!) iOS magic
  27. Finally if the user has an older device, they’ll just

    see an image and the Universal Link with no special UI, But the user can open that in Safari to accept the ticket. @ Recipient URL handling • The solution: • If the recipients device supports iMessage Apps • If the recipient has the app installed • Translate the Universal Link into a deep link, and open the app • Else • Open the iMessage App Store with (new!) iOS magic • Else • Show the image and link separately
  28. So, in the ideal case where the user is on

    iOS 10, has the SeatGeek app installed, and is logged in, When the recipient taps the message, it just opens the app. In the interest of shipping quickly, we decided to let the app do the heavy lifting. iMessage is a convenient inbox and conversation space, And in the future we’d like to let users accept the sent tickets without leaving the conversation. But how does it work currently? @ @ Accepting Tickets • Tapping the message opens the app
  29. And at the top, it extracts the ID and the

    signature. And then uses them to construct a new Transfer object. @ Accepting Tickets
  30. Which are then passed to the app in the `openAppForTransfer`

    method that we saw earlier. And then the app uses them to make the Transfer object again, Which in turn sends them to our API to complete the acceptance. @ Accepting Tickets
  31. We have a couple other features in our iMessage app

    to help Our users see their favorite teams, bands, and shows. Users can send events that they’ve “tracked” in the main app. And they can search for events to send as well. At some point, we’d like to add the ability to purchase tickets in the app, But this was outside of scope as well. @ @ Other Features • Other features • Sending tracked events • Searching for events • To do: buying tickets
  32. While there were some challenges we faced when working on

    the app, Such as changing a beta framework, it was still a worthwhile project. Stripping back the interface to the bare essentials was an excellent exercise. And taught us things about our user experience that can in turn inform decisions on the main app, So that we can make sure we’re providing the simplest most obvious user experience possible. And after all of that, we did get featured! @ @ Challenges • Challenges • Changing Framework • Simplifying both project scope and user experience • We did get featured!
  33. We’re hiring for many different roles, but iOS is especially

    important. This is a great place to work, so if you’re interested, find me after or send me an email. SeatGeek lists tickets from hundreds of sites, and has a thriving business offering a fantastic user experience, But now is a particularly exciting time for us because we recently became the official ticketing partner of Major League Soccer. But MLS is just the beginning – we want to transform the entire industry, So that it’s better for artists and teams, but even more importantly, so that it’s better for people like you and me. Thanks again! @ Thank You! • We’re Hiring iOS Engineers • seatgeek.com/jobs/ios_engineer • An exciting time at a great company • Feel free to reach out with questions • [email protected] • twitter.com/lehrblogger