User:Uroboro: Difference between revisions

641 editsJoined 4 March 2013
(How 2 prefs)
(→‎How 2 prefs: Domain and Notification are different, added Preference Bundle support. Flipswitch sample code)
Line 7: Line 7:
== How 2 prefs ==
== How 2 prefs ==


As opposed to using NSDictionaries and <code>[NSHomeDirectory() stringByAppendingFormat:@"/Library/Preferences/%s.plist", "com.your.tweak"]</code>, here's another alternative to handling preferences on tweaks. Note that I use "com.your.tweak" for both the domain (defaults) and the notification name (PostNotification).
As opposed to using NSDictionaries and <code>[NSHomeDirectory() stringByAppendingFormat:@"/Library/Preferences/%s.plist", "com.your.tweak"]</code>, here's another alternative to handling preferences on tweaks.


=== Tweak.xm ===
=== Tweak.xm ===
Line 18: Line 18:


static NSString const *nsDomainString = @"com.your.tweak";
static NSString const *nsDomainString = @"com.your.tweak";
static NSString const *nsKey = @"enabled";
static NSString const *nsNotificationString = @"com.your.tweak/preferences.changed";
static BOOL enabled;
static BOOL enabled;


static void notificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
static void notificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
NSNumber *n = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:nsKey inDomain:nsDomainString];
NSNumber *n = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:@"enabled" inDomain:nsDomainString];
enabled = (n)? [n boolValue]:YES;
enabled = (n)? [n boolValue]:YES;
}
}


%ctor {
%ctor {
NSNumber *n = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:nsKey inDomain:nsDomainName];
// Set variables on start up
enabled = (n)? [n boolValue]:YES;
notificationCallback(NULL, NULL, NULL, NULL, NULL);


CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, notificationCallback, nsDomainName, NULL, CFNotificationSuspensionBehaviorCoalesce);
// Register for 'PostNotification' notifications
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, notificationCallback, nsNotificationString, NULL, CFNotificationSuspensionBehaviorCoalesce);


// Add any personal initializations
// Add any personal initializations
Line 52: Line 53:
=== Preference plist ===
=== Preference plist ===


Saved in your tweak's folder as <code>layout/Library/PreferenceLoader/Preferences/com.your.tweak.plist</code>, use any of the following
Choose any of the following:


==== Reduced style ====
==== Reduced style ====


Provides a switch on the root section of the preferences (like Airplane Mode). Recommended for configuration-less tweaks.
Provides a switch on the root section of the preferences (like Airplane Mode). Recommended for configuration-less tweaks.
Saved in your tweak's folder as <code>layout/Library/PreferenceLoader/Preferences/com.your.tweak.plist</code>


<pre>{
<pre>{
Line 65: Line 68:
         default = 1;
         default = 1;
         icon = "/Applications/Preferences.app/[email protected]";
         icon = "/Applications/Preferences.app/[email protected]";
         PostNotification = "com.your.tweak";
         PostNotification = "com.your.tweak/preferences.changed";
     };
     };
}
}
Line 73: Line 76:


Provides a pane where other cells can appear (like Wi-Fi). Recommended for configuration-friendly tweaks.
Provides a pane where other cells can appear (like Wi-Fi). Recommended for configuration-friendly tweaks.
Saved in your tweak's folder as <code>layout/Library/PreferenceLoader/Preferences/com.your.tweak.plist</code>


<pre>{
<pre>{
Line 88: Line 93:
             key = enabled;
             key = enabled;
             default = 1;
             default = 1;
             PostNotification = "com.your.tweak";
             PostNotification = "com.your.tweak/preferences.changed";
        }
        // add more cells (dictionaries) here
    );
}</pre>
 
==== PreferenceLoader Style ====
 
Provides a static list of cells. Recommended for Preference Bundles of tweaks.
 
Saved in your tweak's Preference Bundle subproject folder as <code>Resources/com.your.tweak.plist</code>
 
<pre>{
    items = (
        {
            cell = PSSwitchCell;
            defaults = "com.your.tweak";
            label = Enabled;
            key = enabled;
            default = 1;
            PostNotification = "com.your.tweak/preferences.changed";
         }
         }
         // add more cells (dictionaries) here
         // add more cells (dictionaries) here
     );
     );
}</pre>
}</pre>
=== Flipswitches ===
After using the Flipswitch NIC template, modify accordingly
==== Switch.x ====
<source lang="objc">
#import "FSSwitchDataSource.h"
#import "FSSwitchPanel.h"
@interface NSUserDefaults (Tweak_Category)
- (id)objectForKey:(NSString *)key inDomain:(NSString *)domain;
- (void)setObject:(id)value forKey:(NSString *)key inDomain:(NSString *)domain;
@end
static NSString const *nsDomainString = @"com.your.tweak";
static NSString const *nsNotificationString = @"com.your.tweak/preferences.changed";
@interface YourTweakFlipswitchSwitch : NSObject <FSSwitchDataSource>
@end
@implementation YourTweakFlipswitchSwitch
- (NSString *)titleForSwitchIdentifier:(NSString *)switchIdentifier {
    return @"Your Tweak";
}
- (FSSwitchState)stateForSwitchIdentifier:(NSString *)switchIdentifier {
    NSNumber *n = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:@"enabled" inDomain:nsDomainString];
    BOOL enabled = (n)? [n boolValue]:YES;
    return (enabled) ? FSSwitchStateOn : FSSwitchStateOff;
}
- (void)applyState:(FSSwitchState)newState forSwitchIdentifier:(NSString *)switchIdentifier {
    switch (newState) {
    case FSSwitchStateIndeterminate:
        break;
    case FSSwitchStateOn:
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"enabled" inDomain:nsDomainString];
        CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), nsNotificationString, NULL, NULL, YES);
        break;
    case FSSwitchStateOff:
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"enabled" inDomain:nsDomainString];
        CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), nsNotificationString, NULL, NULL, YES);
        break;
    }
    return;
}
@end
</source>


== Other Stuff ==
== Other Stuff ==

Revision as of 13:56, 20 June 2014

Find me on saurik's IRC server, on Twitter, on Reddit, on Github.

Made UnlockEvents and FlipNC.

If you are looking for notifications within a process, give NotificationExplorer a look.

How 2 prefs

As opposed to using NSDictionaries and [NSHomeDirectory() stringByAppendingFormat:@"/Library/Preferences/%s.plist", "com.your.tweak"], here's another alternative to handling preferences on tweaks.

Tweak.xm

@interface NSUserDefaults (Tweak_Category)
- (id)objectForKey:(NSString *)key inDomain:(NSString *)domain;
- (void)setObject:(id)value forKey:(NSString *)key inDomain:(NSString *)domain;
@end

static NSString const *nsDomainString = @"com.your.tweak";
static NSString const *nsNotificationString = @"com.your.tweak/preferences.changed";
static BOOL enabled;

static void notificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
NSNumber *n = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:@"enabled" inDomain:nsDomainString];
enabled = (n)? [n boolValue]:YES;
}

%ctor {
// Set variables on start up
notificationCallback(NULL, NULL, NULL, NULL, NULL);

// Register for 'PostNotification' notifications
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, notificationCallback, nsNotificationString, NULL, CFNotificationSuspensionBehaviorCoalesce);

// Add any personal initializations
}

/*
 * From here onward, write your tweak.
 * To make your tweak actually do stuff when enabled:
if (!enabled) {
     // Do the original algorithm, either by calling:
     // %orig(); //if using logos for methods
     // _functionName(args); //if using MSHook() for functions
} else {
    ...
    // Optionally, do the original algorithm
}
 */

Preference plist

Choose any of the following:

Reduced style

Provides a switch on the root section of the preferences (like Airplane Mode). Recommended for configuration-less tweaks.

Saved in your tweak's folder as layout/Library/PreferenceLoader/Preferences/com.your.tweak.plist

{
    entry = {
        cell = PSSwitchCell;
        label = "Your Tweak";
        defaults = "com.your.tweak";
        default = 1;
        icon = "/Applications/Preferences.app/[email protected]";
        PostNotification = "com.your.tweak/preferences.changed";
    };
}

Extended Style

Provides a pane where other cells can appear (like Wi-Fi). Recommended for configuration-friendly tweaks.

Saved in your tweak's folder as layout/Library/PreferenceLoader/Preferences/com.your.tweak.plist

{
    title = "Your Tweak";
    entry = {
        cell = PSLinkCell;
        label = "Your Tweak";
        icon = "/Applications/Preferences.app/[email protected]";
    };
    items = (
        {
            cell = PSSwitchCell;
            defaults = "com.your.tweak";
            label = Enabled;
            key = enabled;
            default = 1;
            PostNotification = "com.your.tweak/preferences.changed";
        }
        // add more cells (dictionaries) here
    );
}

PreferenceLoader Style

Provides a static list of cells. Recommended for Preference Bundles of tweaks.

Saved in your tweak's Preference Bundle subproject folder as Resources/com.your.tweak.plist

{
    items = (
        {
            cell = PSSwitchCell;
            defaults = "com.your.tweak";
            label = Enabled;
            key = enabled;
            default = 1;
            PostNotification = "com.your.tweak/preferences.changed";
        }
        // add more cells (dictionaries) here
    );
}

Flipswitches

After using the Flipswitch NIC template, modify accordingly

Switch.x

#import "FSSwitchDataSource.h"
#import "FSSwitchPanel.h"

@interface NSUserDefaults (Tweak_Category)
- (id)objectForKey:(NSString *)key inDomain:(NSString *)domain;
- (void)setObject:(id)value forKey:(NSString *)key inDomain:(NSString *)domain;
@end

static NSString const *nsDomainString = @"com.your.tweak";
static NSString const *nsNotificationString = @"com.your.tweak/preferences.changed";

@interface YourTweakFlipswitchSwitch : NSObject <FSSwitchDataSource>
@end

@implementation YourTweakFlipswitchSwitch

- (NSString *)titleForSwitchIdentifier:(NSString *)switchIdentifier {
    return @"Your Tweak";
}

- (FSSwitchState)stateForSwitchIdentifier:(NSString *)switchIdentifier {
    NSNumber *n = (NSNumber *)[[NSUserDefaults standardUserDefaults] objectForKey:@"enabled" inDomain:nsDomainString];
    BOOL enabled = (n)? [n boolValue]:YES;
    return (enabled) ? FSSwitchStateOn : FSSwitchStateOff;
}

- (void)applyState:(FSSwitchState)newState forSwitchIdentifier:(NSString *)switchIdentifier {
    switch (newState) {
    case FSSwitchStateIndeterminate:
        break;
    case FSSwitchStateOn:
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"enabled" inDomain:nsDomainString];
        CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), nsNotificationString, NULL, NULL, YES);
        break;
    case FSSwitchStateOff:
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"enabled" inDomain:nsDomainString];
        CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), nsNotificationString, NULL, NULL, YES);
        break;
    }
    return;
}

@end

Other Stuff

Similar Wanted Pages:

Inheritance hierarchy‏‎ MIG Subsystems
ApplicationScripting.framework/Inheritance hierarchy‏‎ ApplicationScripting.framework/MIG subsystem‏
AppSupport.framework/MIG subsystem
AudioToolbox.framework/Inheritance hierarchy ‏AudioToolbox.framework/MIG subsystem
AVFoundation.framework/Inheritance hierarchy‏ AVFoundation.framework/MIG subsystem
BackBoardServices.framework/Inheritance hierarchy‏ BackBoardServices.framework/MIG subsystem‏‎
‏BulletinBoard.framework/Inheritance hierarchy‏ ‏BulletinBoard.framework/MIG subsystem
ChatKit.framework/MIG subsystem‏
CoreTelephony.framework/Inheritance hierarchy‏‎ CoreFoundation.framework/MIG subsystem
CoreTelephony.framework/MIG subsystem
‏Foundation.framework/MIG subsystem
GraphicsServices.framework/Inheritance hierarchy‏‎ GraphicsServices.framework/MIG subsystem
IH boilerplate/Inheritance hierarchy‏‎ IH boilerplate/MIG subsystem‏‎
IOKit.framework/Inheritance hierarchy‏‎ IOKit.framework/MIG subsystem
IOSurface.framework/Inheritance hierarchy ‏IOSurface.framework/MIG subsystem
MapKit.framework/Inheritance hierarchy MapKit.framework/MIG subsystem
‏Message.framework/MIG subsystem
Preferences.app/Inheritance hierarchy‏ ‏Preferences.app/MIG subsystem
Preferences.framework/MIG subsystem
SpringBoardServices.framework/Inheritance hierarchy‏
TelephonyUI.framework/Inheritance hierarchy TelephonyUI.framework/MIG subsystem
WiFiPicker.servicebundle/Inheritance hierarchy ‏WiFiPicker.servicebundle/MIG subsystem‏