First, some background

A few years ago, while visiting New York, I’d constantly get disoriented by turn-by-turn walking directions on my iPhone. I didn’t care about specific streets and I wished my phone would just tell me the general direction of my destination. On the plane ride back, I started writing an app to do just that. Walk Wellbeyond was born.

Meeting with Friends

Walk Wellbeyond is mainly used to walk to simple destinations like restaurants and stores but sometimes you want to meet up with a friend who is also walking. That’s when it would be useful to have an arrow pointing to the person you’re trying to meet up with. I thought about implementing this functionality but it would require non-trivial server infrastructure and end-to-end encryption, both of which can be tricky to implement

When SharePlay was announced during WWDC 2021 I was excited: the server infrastructure and end-to-end encryption were already taken care of by Apple, and all I had to do was periodically share the location of all participants.

Implementing SharePlay was surprisingly easy. At first, I was worried about the user experience because the WWDC demos didn’t make it all that clear what the user flow would look like.

The UI for initiating a new SharePlay Session

It turns out that there’s a very simple way to detect whether SharePlay is available, such as when the user is on a FaceTime call while running your app. The SharePlay API provides a GroupStateObserver observable object that you can use in your SwiftUI View. All I had to do was check its isEligibleForGroupSession property and when appropriate, display a button that would initiate a “Walk & Meet” session:

    struct DestinationsView: View {
      
      @EnvironmentObject var state: AppState
      @StateObject var groupStateObserver = GroupStateObserver()
      
      var body: some View {

      List {
        
        if groupStateObserver.isEligibleForGroupSession {
          Button {
            state.startSharing()
          } label: {
            HStack {
              Image(systemName: "person.2.fill")
                .font(.system(size: 24))
              Text(state.groupSession == nil ?
                String(localized: "Walk & Meet") :
                String(localized: "Waiting for Others"))
              Spacer()
            }
            .padding()
            .background(Color(.secondarySystemBackground))
            .cornerRadius(10)
          }
        }
        
      }
    }

That’s all that’s required to let the user initiate a SharePlay session while using FaceTime. The rest of the user flow is handled for you by iOS!

Starting the Session

After reading this code, you’re probably wondering what state.startSharing() does. I have an AppState environment object that is available to most UI classes. It keeps of the current state (are you searching or walking?) and if you’re walking what your destination is. There’s not much difference between walking to a static location and a friend, except that your friend probably moves around more.

My Wish List

Unfortunately, SharePlay is only available when you’re using FaceTime. I would have loved it to be available to anyone, especially people texting using Messages. I hope SharePlay is a huge success and Apple will feel compelled to expand this to create more end-to-end encryption tunnels that can integrate voice and video. Why not have a view that shows the Facetime video of a participant? Or make the whole video stream available for additional processing and manipulation? For games, integration with Game Center could have lots of potential. There are privacy implications that would need to be addressed but they don’t go much beyond the use of a camera or photo stream.

The other current pain point is that you get absolutely no information about the participants on your FaceTime connection, not even a name that the user can recognize. So right now, if there are multiple people on the call, Mapless simply shows a tabbed view and you can swipe between different participants, without seeing the name or photo of each participant.