Cephei — General
-
Executes a shell command and returns its output.
Declaration
Objective-C
extern NSString *_Nullable HBOutputForShellCommand(NSString *_Nonnull command)
Swift
func HBOutputForShellCommand(_ command: String) -> String?
Parameters
command
The shell command to run.
Return Value
The output of the provided command, or nil if the command returned with a code other than 0.
-
Executes a shell command and returns its output.
Declaration
Objective-C
extern NSString *_Nullable HBOutputForShellCommandWithReturnCode( NSString *_Nonnull command, int *_Nonnull returnCode)
Swift
func HBOutputForShellCommandWithReturnCode(_ command: String, _ returnCode: UnsafeMutablePointer<Int32>) -> String?
Parameters
command
The shell command to run.
returnCode
A pointer to an integer that will contain the return code of the command.
Return Value
The output of the provided command.
-
The HBPreferences class in Cephei provides an interface for managing user-defined preferences of a tweak, and the default values used when the user has not yet changed a value.
HBPreferences
is very similar toNSUserDefaults
, however it is specifically tailored to iOS tweak development, since tweaks may be loaded into a sandboxed process (most obviously, App Store apps, but also system apps like Safari), or one that runs as theroot
user (for instance, iFile, although these apps are slowly changing their model so they now run as mobile). In both of these cases, usingNSUserDefaults
will result in reading from preferences inside the sandbox, or insideroot
’s home directory; both of which are not what is expected.Advantages
HBPreferences
has overNSUserDefaults
are:- Directly reading the property list from the
mobile
user’s home directory, to support sandboxed apps and apps running asroot
. - Intuitive method of setting a default preference value.
- Updating of the app/tweak’s variables when preferences are changed.
- Keyed subscripting is allowed, which enables simple array syntax.
- Values in the preferences plist are called preferences, not defaults, to avoid ambiguity -
NSUserDefaults
uses “defaults” to refer to both preferences themselves and the fallback values if a key doesn’t exist.
Ensure you read the discussion for
-registerObject:default:forKey:
before using the automatic updating mechanism.-objectForKey:
does not update as another process updates the preferences on iOS 7 or older; if you need to support older iOS versions, use the registration methods instead.As of Cephei 1.17, HBPreferences supports Key-Value Observation. As such, you may subscribe to changes made to preferences through observer callbacks. The
-registerPreferenceChangeBlock:
and-registerPreferenceChangeBlockForKey:block:
methods are provided to subscribe to preference changes via a callback block since Cephei 1.3, and you can additionally observeHBPreferencesDidChangeNotification
.Example usage
In Objective-C/Logos:
HBPreferences *preferences; BOOL doThing; %ctor { preferences = [[HBPreferences alloc] initWithIdentifier:@"ws.hbang.common.demo"]; [preferences registerDefaults:@{ @"Enabled": @YES, @"AnotherSetting": @1.f }]; [preferences registerBool:&doThing default:NO forKey:@"DoThing"]; NSLog(@"Am I enabled? %i", [preferences boolForKey:@"Enabled"]); NSLog(@"Can I do thing? %i", doThing); }
In Swift:
class Preferences { private let preferences = HBPreferences(identifier: "ws.hbang.common.demo") // Example using registration method private(set) var canDoThing: ObjCBool = false // Example using custom getter and setter var anotherSetting: Int { get { preferences["AnotherSetting"] as? Int ?? -1 } set { preferences["AnotherSetting"] = newValue } } // Example using KVO observation private var doThingObserver: NSKeyValueObserving? init() { preferences.register(defaults: [ "Enabled": true, "AnotherSetting": 1 ]) preferences.register(&canDoThing, default: false, forKey: "DoThing") print("Am I enabled? \(preferences["Enabled"] as? Bool ?? false)") print("Can I do thing? \(canDoThing)") } }
References
Security
As of Cephei 1.12, HBPreferences restricts most Apple preferences (identifiers starting with
com.apple.…
) from being read/written from a sandboxed process. This protects against a malicious app using HBPreferences as a way to gather sensitive information or change system preferences without the user’s knowledge. For instance, an App Store app could phish for the user’s Apple ID login, creating a very real-looking login prompt by pre-filling their email address in the username box, or gain access to the numbers/email addresses of people the user has recently contacted.There is currently no way to avoid this restriction while still using HBPreferences. If you need access to Apple preferences, design your code to not need to do this from within the sandbox. This could be done using IPC from an unsandboxed process such as SpringBoard. Avoid sending sensitive information via IPC to sandboxed apps, as they can still get access to data you send through various ways.
See moreDeclaration
Objective-C
@interface HBPreferences : NSObject
Swift
class HBPreferences : NSObject
- Directly reading the property list from the
-
The HBRespringController class in Cephei provides conveniences for restarting the system app (usually SpringBoard). It also ensures battery usage statistics are not lost when performing the restart.
See moreDeclaration
Objective-C
@interface HBRespringController : NSObject
Swift
class HBRespringController : NSObject
-
NSDictionary (HBAdditions) is a class category in Cephei that provides some convenience methods.
See moreDeclaration
Objective-C
@interface NSDictionary (HBAdditions)
-
NSString (HBAdditions) is a class category in Cephei that provides some convenience methods.
See moreDeclaration
Objective-C
@interface NSString (HBAdditions)