2

I have some major issues with the MKSnapshotter when testing my 'Watch Application' / iOS app watch extension on a real iPhone connected to a Apple Watch!

Inside one of my Interface Controllers I call the following function:

  func createMapSnapshot(){
    //Snapshotter for overview image
    self.options = MKMapSnapshotOptions()
    self.options!.region = getEndRegion()
    self.snapshotter = MKMapSnapshotter(options: options!)
    snapshotter!.startWithCompletionHandler() {snapshot, error in

        dispatch_async(dispatch_get_main_queue()) {
            var finalImage = self.drawEndRun(snapshot.image, snapshot: snapshot)

            self.mapImage.setImage(finalImage)
        }
    }
}

This should create an image of the map and fill my WKInterfaceImage with it. As soon as I create the Image my memory jumps from about 3 MB to 20 MB and stays there even if i set options = nil and snapshotter = nil. Also I get the following message printed on the console:

WatchKit Extension[9548:2529231] BSXPCMessage received error for message: Connection interrupted

But here comes the worst part: As soon as I want to create another snapshot my Watch App crashes due to a memory error! I assume that this happens because the snapshotter won't free the memory after allocating it... How can I do that manually or does someone have another idea?

It has nothing to do with the getEndRegion() function! I also tested it with the default snapshotter without options -> same result!

If I test the app in the simulator everything works fine!

UPDATE:

I searched the documentation of MKMapSnapshotter and it says, that it can only deliver a snapshot if the app is in the foreground, thus it can't be rendered from the main Application and the memory allocated to the iOS watch extension is too low, so is there any other way??

Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
iVentis
  • 993
  • 6
  • 19
  • this might be a wording issue and doesn't answer this but (as you say in a comment) the watch app runs on the phone as well -- just to make it clear for 'new' folks – Daij-Djan Apr 30 '15 at 08:28

1 Answers1

0

The simulator has access to a lot more memory than is available to an extension running on your phone. I'd suggest kicking off a request to your iPhone app using openParentApplication:reply: and doing the work there.

Secondary question: why generate an image of a map yourself? WKInterfaceMap is essentially doing that on the Watch for you.

bgilham
  • 5,909
  • 1
  • 24
  • 39
  • 1
    isn't the code of the watch also executed on the phone? – iVentis Apr 29 '15 at 10:16
  • 1
    Yes. But the memory allocated to an extension is much lower than for your main app. – bgilham Apr 29 '15 at 10:16
  • i need an image because i have to draw something on the map which isn't possible with WKInterfaceMap... the openParentApplication doesn't work either.. i get no response when i do this inside my appdelegate: MKMapSnapshotter* snapshotter = [[MKMapSnapshotter alloc] init]; [snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ NSDictionary* dict = @{@"img" : snapshot}; reply(dict); }); }]; – iVentis Apr 29 '15 at 10:17
  • That's because you need to perform your work on a background task. Check here: http://stackoverflow.com/a/29848521/3704092 – bgilham Apr 29 '15 at 10:30
  • This doesn't seem to work either :/ I have a SharedLocation class which performs location stuff..(e.g. post a wormhole on every new location update) in the background. I put the snapshotter inside of this class but the wormhole never arived.. – iVentis Apr 29 '15 at 10:57