1

I'm trying to invoke the Continuity Camera (Mac OS) service programmatically using BOOL NSPerformService(NSString *itemName, NSPasteboard *pboard); API so that the functionality can be hooked behind simple button click. What is the name of the Continuity Camera service that needs to be passed in as itemName parameter?

I can't find the name of the service from com.apple.nsserivcescache.plist file, though from the context menu, the names of the services are "Take Photo" and "Scan Document". I'm not sure if those names will work as they are always associated with the name of the device ( iPhone | iPad ).

Things that I tried.

NSPerformSerice( @"Take Photo", [NSPasteboard generalPasteboard] ); NSPerformSerice( @"<Name of the iPhone> Take Photo", [NSPasteboard generalPasteboard] ); NSPerformSerice( @"<Name of the iPhone>/Take Photo", [NSPasteboard generalPasteboard] );

Naresh Kumar
  • 277
  • 4
  • 18
  • What is the name of Services menu item? – Willeke Jan 08 '19 at 09:18
  • Service Menu Item name is followed by two options "Take Photo" / "Scan Documents". I looked at com.apple.nsservicescache.plist file to find the name of the service used by Continuity Camera feature but couldn't find the name of it. – Naresh Kumar Jan 08 '19 at 22:02
  • Which item names did you try? – Willeke Jan 09 '19 at 10:20
  • Related: [Continuity Camera for macOS and iOS](https://stackoverflow.com/questions/52527491/continuity-camera-for-macos-and-ios). – Willeke Jan 09 '19 at 10:22
  • I tried the following, `NSPerformService( @"Take Photo", [NSPasteboard generalPasteboard] );` `NSPerformService( @" Take Photo", [NSPasteboard generalPasteboard] );``NSPerformService( @"/Take Photo", [NSPasteboard generalPasteboard] );` But none worked. The link that @Willeke points out context menu way to use continuity camera service. I want to execute that service as a part of a button click. – Naresh Kumar Jan 09 '19 at 22:22

1 Answers1

1

I wrote a short post about adding Continuity Camera support to your own app: https://thomas.zoechling.me/journal/2018/10/Continuity.html

You have to implement NSServicesMenuRequestor to indicate that you can handle images from the pasteboard:

override func validRequestor(forSendType sendType: NSPasteboard.PasteboardType?, returnType: NSPasteboard.PasteboardType?) -> Any? {
    if let pasteboardType = returnType,
        NSImage.imageTypes.contains(pasteboardType.rawValue) {
        return self
    } else {
        return super.validRequestor(forSendType: sendType, returnType: returnType)
    }
}

By implementing the above method, menus of the current first responder (e.g. a menu of a button) will get auto-populated with the Continuity Camera menu items.

The items of that menu will start the CC UI which then calls readSelection(from: pasteboard) when the user performs a capture.
You can read the pasteboard contents from there:

func readSelection(from pasteboard: NSPasteboard) -> Bool {
    guard pasteboard.canReadItem(withDataConformingToTypes: NSImage.imageTypes) else { return false }
    guard let image = NSImage(pasteboard: pasteboard) else { return false }

    self.imageView.image = image
    return true
}

It also should be possible to control where the CC related menu items get inserted. There is a related NSMenuItemImportFromDeviceIdentifier constant, but I haven't figured out yet how to use this. (Some context in this Twitter thread: https://twitter.com/weichsel/status/1052980223891972096)

Thomas Zoechling
  • 34,177
  • 3
  • 81
  • 112