Плагины устанавливаются в папку PreferencePanes.
Mac OS X в будущем не будет поддерживать 32-bit.
1. Создадим новый проект с именем NewDefaults из раздела System Plug-in по шаблону Preference Pane.
2. Сохраним проект в папку projects в Documents
3. После создания проекта в нем будут файлы типа:
.tiff
Tagged Image File Format (tiff).
NewDefaults.tiff - иконка (32 x 32), которая будет отображаться в System Preferences.
.prefPane
Preference pane.
NewDefaults.prefPane - продукт сборки.
4. Если после сборки открыть файл NewDefaults.prefPane, то будет предложено установить его.
5. В настройках TARGETS в секции Info опция Preference Pane icon file содержит наименование файла с иконкой только без расширения например, NewDefaults
Опция Copyright (human- readable) может содержать имя разработчика или компании, например, Copyright © 2014 Devtype Software. All rights reserved.
6. При повторном запуске продукта сборки будет предложена переустановка.
7. Создадим 3 Check Box-a:
Mac OS X в будущем не будет поддерживать 32-bit.
1. Создадим новый проект с именем NewDefaults из раздела System Plug-in по шаблону Preference Pane.
2. Сохраним проект в папку projects в Documents
3. После создания проекта в нем будут файлы типа:
.tiff
Tagged Image File Format (tiff).
NewDefaults.tiff - иконка (32 x 32), которая будет отображаться в System Preferences.
.prefPane
Preference pane.
NewDefaults.prefPane - продукт сборки.
4. Если после сборки открыть файл NewDefaults.prefPane, то будет предложено установить его.
5. В настройках TARGETS в секции Info опция Preference Pane icon file содержит наименование файла с иконкой только без расширения например, NewDefaults
Опция Copyright (human- readable) может содержать имя разработчика или компании, например, Copyright © 2014 Devtype Software. All rights reserved.
6. При повторном запуске продукта сборки будет предложена переустановка.
7. Создадим 3 Check Box-a:
- Enabling and disabling Launchpad fading
- Showing and hiding hidden files in the Finder
- Showing and hiding the Library folder in the current user's home folder
8. В NewDefaults.h добавляем символы, переменные, и методы:
Здесь мы не использовали @property и @synthesize поэтому Xcode не создаст accessor методы автоматически. Это также означает что нужно обернуть в фигурные скобки объявление переменных экземпляра.
9. В NewDefaults.m добавляем:
Все NS объекты являются immutable (unchangeable) если они в своем названии не содержат Mutable. Чтобы получить mutable объект из inmutable надо ему послать сообщение mutableCopy.
10. Выбираем NewDefaults.xib, далее выбираем File's Owner, и в Custom Class вбиваем NewDefaults
11. Все checkbox-ы ПКМ перетягиваем на File's Owner и выбираем myButtonAction
12. Далее наоборот File's Owner ПКМ перетягиваем на checkbox-ы и выбираем соответствующие им IBOutlet-ы.
#import <PreferencePanes/PreferencePanes.h>
@interface NewDefaults : NSPreferencePane
// Define the path to the Library folder
// in the users home folder
#define D_HOME_LIBRARY_PATH @"~/Library"
// Define the path to the defaults command
#define D_DEFAULTS_PATH @"/usr/bin/defaults"
// Define the read command
#define D_READ_COMMAND @"read"
// Define the Finders domain
#define D_DOMAIN_FINDER @"com.apple.finder"
// Define the Docks domain
#define D_DOMAIN_DOCK @"com.apple.dock"
// Define the defaults command to show
// hidden files in the Finder
#define D_DEFAULTS_SHOW_FILES \
"defaults write com.apple.finder AppleShowAllFiles YES"
// Define the defaults command to hide
// hidden files in the Finder
#define D_DEFAULTS_HIDE_FILES \
"defaults write com.apple.finder AppleShowAllFiles NO"
// Define the defaults command to delete
// the Finder hidden files key
#define D_DEFAULTS_DEL_HIDE_FILES \
"defaults delete com.apple.finder AppleShowAllFiles"
// Define the defaults commands to enable
// Launchpad fading
#define D_DEFAULTS_DEL_SHOW_DURATION \
"defaults delete com.apple.dock springboard-show-duration"
#define D_DEFAULTS_DEL_HIDE_DURATION \
"defaults delete com.apple.dock springboard-hide-duration"
// Define the defaults commands to disable
// Launchpad fading
#define D_DEFAULTS_SHOW_DURATION_0 \
"defaults write com.apple.dock \
springboard-show-duration -int 0"
#define D_DEFAULTS_HIDE_DURATION_0 \
"defaults write com.apple.dock \
springboard-hide-duration -int 0"
// Define the command to restart
// the Finder
#define D_RESTART_FINDER "killall Finder"
// Define the command to restart
// the Dock
#define D_RESTART_DOCK "killall Dock"
// Define the key to show / hide hidden files
#define kHiddenFileKey @"AppleShowAllFiles"
// Define the key to disable Launchpad fading
#define kSpringboardShowTime @"springboard-show-duration"
#define kSpringboardHideTime @"springboard-hide-duration"
// Define a string equal to YES
#define D_YES @"YES"
{
/*
Create the user interface elements
*/
// Buttons - A Check Box is a button
IBOutlet NSButton* enableHiddenFilesCheckbox;
IBOutlet NSButton* enableLaunchpadFadeCheckbox;
IBOutlet NSButton* enableHomeLibraryCheckbox;
}
- (void)mainViewDidLoad;
/*
Create the Preference Pane interface for the buttons
*/
- (IBAction)myButtonAction:(id)sender;
/*
Define the interface to a method that will use
the defaults command to retrieve a domain
defaults value for a key
*/
- (NSString *) readDefaults: (NSString *)a_domain
forKey: (NSString *)a_key;
@end
Здесь мы не использовали @property и @synthesize поэтому Xcode не создаст accessor методы автоматически. Это также означает что нужно обернуть в фигурные скобки объявление переменных экземпляра.
9. В NewDefaults.m добавляем:
#import "NewDefaults.h"
@implementation NewDefaults
/*
Create the Preference Pane implementation for when
a checkbox is clicked this method is called with the
sender equal to the check box that invoked it
*/
- (IBAction)myButtonAction:(id)sender;
{
// Disable sudden termination, it is not
// safe to kill the System Preferences
[[NSProcessInfo processInfo] disableSuddenTermination];
// Was the Show ~/Library Folder button pressed?
if (YES == [sender isEqual: enableHomeLibraryCheckbox])
{
// Get a URL reference to the file
NSURL *l_url =
[NSURL fileURLWithPath:
[D_HOME_LIBRARY_PATH stringByExpandingTildeInPath]];
// If the checkbox is ON (checked) then
if (NSOnState == [sender state])
{
// Set the URL IsHidden value to NO
// This makes the folder Visible in the Finder
[l_url setResourceValue:
[NSNumber numberWithBool:NO]
forKey:NSURLIsHiddenKey
error:Nil];
}
// else the checkbox is OFF (unchecked)
else
{
// Set the URL IsHidden value to YES
// This makes the folder Invisible in the Finder
[l_url setResourceValue:
[NSNumber numberWithBool:YES]
forKey:NSURLIsHiddenKey
error:Nil];
}
}
// Was the Show Hidden Files in Finder button pressed?
if (YES == [sender isEqual: enableHiddenFilesCheckbox])
{
// If the checkbox is ON (checked) then
if (NSOnState == [sender state])
{
// Execute the command to enable showing hidden files
system(D_DEFAULTS_SHOW_FILES);
}
// else the checkbox is OFF (unchecked) then
else
{
// Execute the command to disable showing hidden files
system(D_DEFAULTS_HIDE_FILES);
}
// Execute the system command to restart the Finder
system(D_RESTART_FINDER);
}
// Was the Enable Launchpad fading button pressed?
if (YES == [sender isEqual: enableLaunchpadFadeCheckbox])
{
// If the checkbox is ON (checked) then
if (NSOnState == [sender state])
{
// Execute the commands to enable fading
system(D_DEFAULTS_DEL_SHOW_DURATION);
system(D_DEFAULTS_DEL_HIDE_DURATION);
} else {
// Execute the commands to disable fading
system(D_DEFAULTS_SHOW_DURATION_0);
system(D_DEFAULTS_HIDE_DURATION_0);
}
// Execute the system command to restart the Finder
system(D_RESTART_DOCK);
}
// Enable sudden termination, it is
// safe to kill the System Preferences
[[NSProcessInfo processInfo] enableSuddenTermination];
}
- (void)mainViewDidLoad
{
}
/*
This method will execute the command line tool defaults
to read a value from a domain for a specific key
Input:
a_domain - a reverse domain id for the defaults to read
a_key - a key value to read
Output:
Either the string value of the result or Nil if there
is no value to return.
*/
- (NSString *) readDefaults: (NSString *)a_domain
forKey: (NSString *)a_key
{
// Create a string reference to hold the result
NSString *l_result;
// Create and initialize a new task
NSTask *l_readTask = [[NSTask alloc] init];
// Assign the launch path for the task
[l_readTask setLaunchPath:D_DEFAULTS_PATH];
// Create an array with the read command
// and the domain and key values
NSArray *l_arguments =
[NSArray arrayWithObjects: D_READ_COMMAND,
a_domain,
a_key,
nil];
// Assign the argument array to the NSTask
[l_readTask setArguments:l_arguments];
// Create a new pipe to read the results
// of the command
NSPipe *l_pipe = [NSPipe pipe];
// Assign the read pipe to the NSTask
[l_readTask setStandardOutput:l_pipe];
// Retrieve the pipe's fileHandleForReading
NSFileHandle *l_file = [l_pipe fileHandleForReading];
// Launch the Task
[l_readTask launch];
// Release the Task - this is not needed on
// Mac OS X 10.7 but is also harmless
// [l_readTask release];
// Read all the output data from the Task
// and create a mutable copy
// The NSTask will exit when done
NSMutableData *l_data =
[[l_file readDataToEndOfFile] mutableCopy];
// If the NSTask ended but returned
// nothing, then return a Nil
if (0 == [l_data length])
{
return Nil; }
// The defaults command will append a newline (\n)
// character to its output. This trims that
// character off so that it is not included in
// the returned value
[l_data setLength:[l_data length] - 1];
// Create a new string from the remaining
// returned data
l_result = [[NSString alloc] initWithData:l_data
encoding:NSUTF8StringEncoding];
// Return the final string
return l_result;
}
/*
The didSelect delegate method is called whenever
the Preference Pane is displayed, even if the
System Preferences were not quit and relaunched
*/
- (void) didSelect
{
// Read the current setting for
// Showing Hidden files in he Finder
NSString *l_showHiddenFile = [self readDefaults: D_DOMAIN_FINDER forKey:kHiddenFileKey];
// Read the current setting for
// Disabling launchpad fading
NSString *l_launchpadFadeOut =
[self readDefaults: D_DOMAIN_DOCK
forKey:kSpringboardHideTime];
NSString *l_launchpadFadeIn =
[self readDefaults: D_DOMAIN_DOCK
forKey:kSpringboardShowTime];
// Assume everything is off, later we will
// turn the correct things back on
[enableHiddenFilesCheckbox setState: NSOffState];
[enableLaunchpadFadeCheckbox setState: NSOffState];
[enableHomeLibraryCheckbox setState: NSOffState];
// If the show hidden files value was found
if (l_showHiddenFile)
{
// If the show hidden files value is YES
if ([D_YES isEqual: l_showHiddenFile])
{
// Turn the check box on in the
// interface
[enableHiddenFilesCheckbox setState: NSOnState];
} else {
// Execute the system command to delete
// the setting
system(D_DEFAULTS_DEL_HIDE_FILES);
} }
// If both launchpad values were found
if ((l_launchpadFadeOut) &&(l_launchpadFadeIn))
{
// If either launchpad values is not equal to 0
if ((0 != [l_launchpadFadeOut integerValue]) ||
(0 != [l_launchpadFadeIn integerValue]))
{
// Turn the check box on in the
// interface
[enableLaunchpadFadeCheckbox setState: NSOnState];
}
}
else {
// Turn the check box on in the
// interface
[enableLaunchpadFadeCheckbox setState: NSOnState];
}
// Create a URL object that references the
// Library file in the users home directory
NSURL *l_url = [NSURL fileURLWithPath: [D_HOME_LIBRARY_PATH
stringByExpandingTildeInPath]];
// Define a NSNumber pointer to hod the result
// of the getResourceValue method
NSNumber *l_isHidden;
// Get the value of the IsHidden attribute
BOOL l_result = [l_url getResourceValue:&l_isHidden
forKey:NSURLIsHiddenKey error:Nil];
// If a value was returned
if (l_result)
{
// If the returned value was NO
if (NO == [l_isHidden boolValue])
{
// Turn the check box on in the
// interface
[enableHomeLibraryCheckbox setState: NSOnState];
}
}
}
@end
Все NS объекты являются immutable (unchangeable) если они в своем названии не содержат Mutable. Чтобы получить mutable объект из inmutable надо ему послать сообщение mutableCopy.
10. Выбираем NewDefaults.xib, далее выбираем File's Owner, и в Custom Class вбиваем NewDefaults
11. Все checkbox-ы ПКМ перетягиваем на File's Owner и выбираем myButtonAction
12. Далее наоборот File's Owner ПКМ перетягиваем на checkbox-ы и выбираем соответствующие им IBOutlet-ы.