How do I exactly use MMWormhole with Swift?

4k views Asked by At

I have an iPhone application and added a WatchKitExtension. From the iPhone App I want to pass a String to the WatchApp which is supposed to change an image on the Watch.

  • What I already did was to download the source files and import the MMWormhole.m & .h. They are written in Obj-C and so Xcode automatically bridged them for me.
  • I also added an app group and activated it for my WatchExtension & my iPhone target

In the tutorial on GitHub it says I have to initialize the wormhole with:

self.wormhole = [[MMWormhole alloc] initWithApplicationGroupIdentifier:@"group.com.mutualmobile.wormhole"
                                                                          optionalDirectory:@"wormhole"];

...and send a message using:

[self.wormhole passMessageObject:@{@"titleString" : title} 
                         identifier:@"messageIdentifier"];

But I have actually no idea where to put that, I am using Swift in my iPhone application and the WatchExtension.

Can anyone please help me there?

2

There are 2 answers

6
prawn On BEST ANSWER

I suppose it depends on different applications, but for one application I put the listeners in the didFinishLaunchingWithOptions method of my app delegate in the main iOS app. This was because the user would be using the watch, and they would be relaying information off to the phone

There were multiple listeners...

var wormhole = MMWormhole(applicationGroupIdentifier: "group", optionalDirectory: nil)

wormhole.listenForMessageWithIdentifier("identifier", listener: { (message) -> Void in
                //do stuff
})

wormhole.listenForMessageWithIdentifier("identifier2", listener: { (message) -> Void in
            //do stuff
})

wormhole.listenForMessageWithIdentifier("identifier3", listener: { (message) -> Void in
            //do stuff
})

And then in a WKInterfaceController, I sent a message. Sometimes in an action, sometimes in the willActivate method. It really depends on the flow of your app

var wormhole = MMWormhole(applicationGroupIdentifier: "group", optionalDirectory: nil)
    @IBAction func buttonPushed(){            
        wormhole.passMessageObject("object", identifier: "identifier1")
    }

This can work both ways though, I could have very easily put a listener in my watch which would wait for messages initiated by some Interface Controller on the phone.

0
Dan Rosenstark On

Here are my instructions. Hopefully they help you with the simplest use case and then you can expand from there. (Remember to structure your code so that it actually makes sense!)

  • Get MMWormhole (the .h and the .m) added to your project. If you know how to use Cocoapods, do that, but otherwise, just use git submodules. (I use git submmodules)
  • Because you need the .h to be visible from Swift, you need to use a bridging header.
  • Set up an App Group, which requires using the Developer Portal. Link is here
  • In your iPhone build target -> Capabilities -> App Groups and add your group. If all three checkboxes do not go perfectly, go back to the Developer Portal and make sure everything is right or start again.

MMWormhole, iPhone Side

Set up the wormhole somewhere you can reach it. NOTE: your group ID has to be the one from above!

let wormhole = MMWormhole(applicationGroupIdentifier: "group.testMe.now", optionalDirectory: nil)
wormhole.listenForMessageWithIdentifier("wormholeMessageFromWatch", listener: { (message ) -> Void in
    if let messageFromWatch = message as? String {
          // do something with messageFromWatch
    }
})

iPhone App Sends String

wormhole.passMessageObject("message from phone to watch", identifier: "wormholeMessageFromPhone")

iPhone app registers to receive and sends again in the callback via MMWormhole (asynchronous but cool)

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    universe.initWormhole(.phone, messageHandler: { (message) -> () in
        universe.wormhole.passMessageObject("the phone got \(message)", identifier: "wormholeMessageFromPhone")
    })
    return true
}

MMWormhole, Apple Watch Side

Set up the wormhole somewhere you can reach it. NOTE: your group ID has to be the one from above!

let wormhole = MMWormhole(applicationGroupIdentifier: "group.testMe.now", optionalDirectory: nil)
wormhole.listenForMessageWithIdentifier("wormholeMessageFromPhone", listener: { (message ) -> Void in
    if let messageFromPhone = message as? String {
          // do something with messageFromPhone
    }
})

MMWormhole, watch app registers to receive

override func awakeWithContext(context: AnyObject?) {
    super.awakeWithContext(context)
    universe.initWormhole(.watch, messageHandler: { (message) -> () in
        println("MMWormhole Message Came to Watch: \(message)")
    })
}

MMWormhole, watch app sends

// force open the parent application because otherwise the message goes nowhere until the app is opened
WKInterfaceController.openParentApplication(["":""], reply: nil) 
universe.wormhole.passMessageObject("[from watch to phone]", identifier: "wormholeMessageFromWatch")