Need detailed information about FIFinderSync

arggharggh FKMember ✭✭

Hello,

I'm trying to use Xamarin.Mac to write a Finder Sync Extension for my project. I managed to register the extension in finder by following the example project. However, I am having difficulties in understanding how to get folder observers to work. Also I'd like to know how to properly debug an extension or log some information. This is my current setup:

            [Register("FinderSync")]
                public partial class FinderSync : FIFinderSync
                {
                    public FinderSync() {
                        var testUrl = new NSUrl("/Users/devmcdevface/test");

                        FIFinderSyncController.DefaultController.DirectoryUrls = new NSSet(
                            new NSUrl[] { testUrl }
                        );
                    }

                    public override void BeginObservingDirectory(NSUrl url) {
                        // Do something here.
                    }
  1. Am I setting up the DirectoryUrls correctly? Do I need to pass NSUrls there?
  2. I verified BeginObservingDirectory was not being called upon viewing the directory (I removed the testing code because it it is too embarrassing to show it in public). I my understanding that should have happened in this setup, right?
  3. What can I do to make this piece of code debuggable? Do I need to manually attach to the Visual Studio debugger to the extension process somehow?

Right now I'm kind of stuck and ran out of ideas. I'd really appreciate any help on getting the basics of this stuff running.
Thank you very much! :smile:

Posts

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    First things first, take a look at the sample:

    https://github.com/xamarin/mac-samples/blob/master/ExtensionSamples/FinderSyncExtension/FinderSync.cs

    and realize you are in a bit of a world of hurt (but it's workable given enough effort),.

    Second thing is to make sure your extension is enabled and loaded:

    • Make sure your extension is signed. Apple refuses to touch many sandbox/extensions without signing these days, arbitrarily.
    • Add your extension to a container application and launch the container
    • System Preferences -> Extensions and enable the plugin under Finder
    • Switch to finder, open console and look for output from pluginkit

    When pluginkit decides your extension is "bad', it will refuse to load it with very little output.

    I've personally hung Finder multiple times so hard I have to restart the OS (even in Xcode!), so if things start acting too weird keep that in mind.

    Once you get your extension loaded, you can start making progress.

    Am I setting up the DirectoryUrls correctly? Do I need to pass NSUrls there?

    Unsure, never used that API, but it looks right.

    I verified BeginObservingDirectory was not being called upon viewing the directory

    Make sure your extension is loaded / running first. Adding a temporary button to your finder UI is a great method.

    What can I do to make this piece of code debuggable? Do I need to manually attach to the Visual Studio debugger to the extension process somehow?

    You are out of luck here. :( Debugging extensions is something we don't support yet, and is a bit more complicated than you'd think. I would suggest using NSLog as noted here and looking in the Console.

    I'm sorry the process is less than ideal. Much of pluginkit is considered "non-public APIs" and my interactions with it suggest it is all async with race conditions on enable/disabling things automatically.

  • arggharggh FKMember ✭✭

    Chris, thank you very much for you comprehensive answer!

    Meanwhile I found out the reason for my directories not being watched is because NSUrl expects a fully qualified domain here, hence I needed to pass file:///my/local/folder instead of the posix path.

    As for updating the extension after a (re-)build process I realised almost every time I needed to killall Finder and uncheck-recheck the extension in system prefs to see my changes. I also noticed changing the name of the extension could take quite a while to become visible in the extensions settings, but will be eventually. This process may be a bit tedious, but not as tedious as coding in the blind without any debugging or logging.

    That being said, I'm going to try NSLog now, hopefully it will work.

    Again thanks for your help, I'm sure I will be back soon with more questions ;-)

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    As for updating the extension after a (re-)build process I realised almost every time I needed to killall Finder and uncheck-recheck the extension in system prefs to see my changes

    Yes, I've seen that as well. Another thing you can do is to force a clean on your container solution instead. Then if you give pluginkit a second, it'll normally notice and remove your plugin from the list / Finder and you can avoid killall.

    I had coded up a number of nicer interactions with Apple's pluginkit when we first implemented extensions but ran into unresolvable issues due to how limited the public API is. I have less than nice things to say about it.

    Please feel free to post questions, I'm happy to help you tough through any issues with extensions.

  • arggharggh FKMember ✭✭
    edited October 20

    Thanks for your support! Luckily I was able to setup the project as intended, however, I ran into a couple of problems while doing so and I thought it might be a good idea to share the experience.

    In my case I implemented the communication between container app and extension using CFMessagePorts. To do so, you need to enable the App Groups feature in entitlements.plist and have the Message Port name carry a suffix (e.g.
    if "group.com.myapp" is the App Group then your Mach port name should be something like "group.com.myapp.whatever").

    A very important thing: After changing the group name I needed to restart the machine in order to get the communication working. Usually I never ever shutdown my machine at work and this took me a day and a half to figure out, so I wanted to share this information in order to help saving some precious time eventually :)

    Bottom line: When working with extensions, always think of restarting the process / rebooting the machine before loosing your head.

Sign In or Register to comment.