Finder Sync Badge Extension Handling - objective-c

I am trying to create a Finder Sync Extension,in yosemite to show badge in files and folder.
I am on the move, but i have no idea how to turn off extension(remove from extensions list in preferences) when my containing application terminate. Any help is appreciated.

Try it..
Reload Directory in Finder
// Reload Finder (change the word directory to file if updating file)
NSAppleScript * update = [[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:#"tell application \"Finder\" to update POSIX directory \"%#\"",path]];
[update executeAndReturnError:nil];
Code to Enable Extension (bundle ID)
system("pluginkit -e use -i com.xyz.finderExt")
Code to Disable Extension (bundle ID)
system("pluginkit -e ignore -i com.xyz.finderExt")

code to remove from extensions list in preferences
pluginkit -r "/Applications/App-name/Contents/Plugins/extension-name.appex"

Related

How to enable FinderSync Extension in macOS System Preferences

I am integrating FinderSync Extension in my Cocoa Application to show badges in files and folders. Look at the below two scenario:
When i run application using FinderSync Extension (like DemoFinderSync) look at the blue popup in the below image, in that case Extension is added in the System Preference with Check mark and called that principal class "FinderSync.m" as well.
When i run application using my Application Scheme (like DemoApp) look at the blue popup in the below image, in that case Extension is added in the System Preference but without check mark and that principal class "FinderSync.m" do not call and FinderSync Extension does not work in this case.
Does anybody have an idea how to enable Finder Extension in the System Preference using second scenario?
Non-debug scheme (#if !DEBUG):
system("pluginkit -e use -i com.domain.my-finder-extension");
When running under debugger give path to your extension directly:
NSString *pluginPath = [[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:#"My Finder Extension.appex"];
NSString *pluginkitString = [NSString stringWithFormat:#"pluginkit -e use -a \"%#\"", pluginPath];
system([pluginkitString cStringUsingEncoding:NSUTF8StringEncoding]);
Specify this in your applicationDidFinishLaunching method. You should also manually turn this on only once so that if user turned your extension off in the System Preferences you don't turn it on every time your application starts. I set an NSUserDefaults key the first time user launches my app that has the finder sync extension support.
I got the solution:
Code to Enable Extension (bundle ID)
system("pluginkit -e use -i YourAppBundleID")
Code to Disable Extension (bundle ID)
system("pluginkit -e ignore -i YourAppBundleID")
Before i used:
system("pluginkit -e use -i AppBundleID.FinderSync")
so just remove ".FinderSync" its working.
Linking an answer I found on the Apple developer forum:
https://forums.developer.apple.com/thread/77682
When your App is outside the Sandbox, you can use:
Objective-C:
system("pluginkit -e use -i <yourFinderExtensionBundleID>");
Swift:
let pipe = Pipe()
let task = Process()
task.launchPath = "/usr/bin/pluginkit"
task.arguments = ["-e", "use", "-i", "<yourFinderExtensionBundleID>"]
task.standardOutput = pipe
let file = pipe.fileHandleForReading
task.launch()
let result = NSString(data: file.readDataToEndOfFile(), encoding:

OS X shell script to add/remove App extension

I am creating a FinderSync Extension for my application like Dropbox do. Now I need to register and unregister this extension from Extensions(in System preference) programmatically.
Dropbox implemented this feature in recent release .
How to unregister and register an extension dynamically using applescipt.
Try pluginkit on the shell (.sh script)
# add it to DB.
pluginkit -a "/Applications/YourApp.app/Contents/PlugIns/FinderSyncExt.appex/"
# enable it
pluginkit -e use -i com.your-application.FinderSyncExt

NSAppleScript with administrator previleges fails when application is launched from package maker

I have a MAC OSX cocoa application,where i used NSAppleScript to run some script with administrator privileges .The application works fine when it is launched manually or from any other script .
But NSAppleScript doesn't launch the intended script when i tried to launch the application from package maker .
I have made a postflight script to launch the application from package maker .
Postflight:
#!/bin/sh
open pathOFApp
NSAppleScript usage:
NSDictionary *error = [NSDictionary new];
NSAppleScript *appleScript = [[NSAppleScript new] initWithSource:#"do shell script \"pathOFScript \" with administrator privileges"];
if ([appleScript executeAndReturnError:&error]) {
NSLog(#"-----success --------");
}
else{
NSLog(#"-------Failure-----");
}
Please help to fix this .
I don't know the answer with applescript/PackageMaker, but have you tried using the unix security tool to launch your executable? I think it's been available since 10.5. You can probably combine this and your executable in one statement too.
/usr/bin/security execute-with-privileges /path/to/executable
Got the solution for this .Since postflight script is launched with the root permission by packageMaker it was creating some permission issue with the NSAppleScript . Launching the application as "sudo open MyApp" in postflight will resolve the issue.

How to set default application for specific file types in Mac OS X?

In Mac OSX lion, I'm trying to set default application for specific file types.
Using the below apple script, we can set the default application for the specific "file.abc".
tell application "System Events"
set default application of file "/Users/test/Desktop/file.abc" to "/Applications/TextEdit.app"
end tell
But I want to set the same application as default for all the files having the filetype or extension as "abc".
I have tried the following to get it done. It added an entry in <HOME>/Library/Preferences/com.apple.LaunchServices.plist. But the files are not opened with the specified application.
defaults write com.apple.LaunchServices LSHandlers -array-add "<dict><key>LSHandlerContentTag</key><string>abc</string><key>LSHandlerContentTagClass</key><string>public.abc</string><key>LSHandlerRoleAll</key><string>com.apple.textedit</string></dict>"
Hope somebody knows what i m missing to achieve it.
Answer Found :
defaults write com.apple.LaunchServices LSHandlers -array-add "<dict><key>LSHandlerContentTag</key><string>ugurugu</string><key>LSHandlerContentTagClass</key><string>public.filename-extension</string><key>LSHandlerRoleAll</key<string>org.videolan.vlc</string></dict>"
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user
Maybe you're doing nothing wrong but that the com.apple.launchservices file just needs to be reloaded. You can logout, wait a few minutes or force launchservices to restart. In the following example I say that public.comma-separated-values-text files (note:This doesn't mean that every CSV file is this content-type) must be opened with TextEdit instead of Excel.
do shell script "defaults write com.apple.LaunchServices LSHandlers -array-add '{ LSHandlerContentType = \"public.comma-separated-values-text\"; LSHandlerRoleAll = \"com.apple.TextEdit\"; }'"
do shell script "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user"
I'm not sure if you're only trying to do this programmatically. Are you?
Otherwise:
On the file, choose "get info", and under "open with" select the name of the application.
Click on the button "Change All"
You might want to take a look at RCDefaultApp and its source code. It's a program that lets you set which file types are opened by which apps in Launch Services.

Launch Finder window with specific files selected

I'm trying to programmatically launch an OS X Finder window from an Xcode project. I need the window to open to a specific folder and have specific files within that folder automatically selected.
This is similar to the "Show in Finder" functionality used in Xcode and related apps.
Does anyone know how to do this in either Objective-C, Swift, AppleScript, or Finder command-line parameters?
Objective-C version:
NSArray *fileURLs = [NSArray arrayWithObjects:fileURL1, /* ... */ nil];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:fileURLs];
$ open -R <path-to-reveal>
Another AppleScript flavor - the Finder's reveal command will both open a window to the containing folder and select the item(s). If there are multiple containing folders, multiple Finder windows will be opened.
tell application "Finder"
to reveal {someAlias, "path/to/POSIXfile" as POSIX file, etc}
Swift version:
let paths = ["/Users/peter/foo/bar.json"]
let fileURLs = paths.map{ NSURL(fileURLWithPath: $0)}
NSWorkspace.sharedWorkspace().activateFileViewerSelectingURLs(fileURLs)
I'm finding that activateFileViewerSelectingURLs is not working on Yosemite (at least when in separate space from Finder). It will cause a switch to the Finder's space but won't seem to select the URL. Using:
- (BOOL)selectFile:(NSString *)fullPath inFileViewerRootedAtPath:(NSString *)rootFullPath
will switch spaces from full screen app and select path.
When opening a file at path:
NSString* path = #"/Users/user/Downloads/my file"
NSArray *fileURLs = [NSArray arrayWithObjects:[NSURL fileURLWithPath:path], nil];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:fileURLs];
Swift 3.2/4.0 Version:
NSWorkspace.shared.activateFileViewerSelecting([outputFileURL])
Reveal multiple files in Finder
As open -R <path-to-reveal> only works for single file.
We can use Apple Script instead.
From user866649's answer, we can port it to a shell script as the following:
osascript -e 'tell application "Finder" to reveal {"path/to/file1" as POSIX file, "path/to/file2" as POSIX file} activate'
Just created a utility script:
finder.sh
#!/usr/bin/env bash
join() {
local d=$1 s=$2
shift 2 && printf %s "$s${#/#/$d}"
}
lst=()
for f in "$#"; do
lst+=("\"$f\" as POSIX file")
done
files=$(join , "${lst[#]}")
osascript -e "tell application \"Finder\" to reveal {$files} activate"
Then try it:
chmod +x finder.sh
./finder.sh ~/Downloads ~/Desktop
It should open Finder and selects both Downloads and Desktop folder.