Use the ShortLook API to create plugins that provide contact icons for third-party applications to ShortLook.
- Setup your development environment just as you would to make tweaks, including Theos.
- Download the API template and extract it's contents.
- Rename your main class (DD_RENAMETHIS_ContactPhotoProvider).
- Using the Info.plist reference, change any values you may need to in
Info.plist
. - Implement your logic inside your main class's
contactPhotoPromiseOfferForNotification:
method (details). - Configure your
Makefile
andcontrol
as you would a normal tweak, using these tips.
- Any format supported by iOS.
- Around 1:1 in aspect ratio (or else it will be zoomed in).
- Above
152x152px
in size (@3x
, preferably).
Every provider plugin must have the following two things:
- An
Info.plist
file describing how ShortLook should register the provider: Documentation Example. - An executable with (a) class(es) conforming to
DDNotificationContactPhotoProviding
: Documentation Example
The Info.plist
file specifies to ShortLook how it should load and handle this provider plugin internally. Every Info.plist file should have the following keys:
CFBundleDisplayName
, string: A short name for what this plugin provides. In most cases, it should just be the name of the app you are providing for (e.g., Twitter).DDNotificationExternalProviderClasses
dictionary: A dictionary of provider classes, and the bundle identifiers they provide for. The key should represent your class name, and it's value may be either a string or array of strings containing the bundle identifiers of apps to provide for.DDNotificationExternalProviderAPIVersion
integer: Must equal 1. The ShortLook API version to use. This is to ensure that future updates with potentially breaking API changes do not crash ShortLook. These will be rare, if ever, but exists for future-proofing.
If you'd like to see a working version, check out an example of Info.plist here.
Now that you've declared how ShortLook should load your plugin, you can start implementing the operations to receive contact photos.
You will make a class that inherits from NSObject
and conforms to DDNotificationContactPhotoProviding
. You should import ShortLook-API.h
in your project for ease of use.
Each provider class implements the following method:
/// Returns an offer to fulfill a promise to provide a contact photo for a notification.
- (DDNotificationContactPhotoPromiseOffer *)contactPhotoPromiseOfferForNotification:(DDUserNotification *)notification;
If you'd like to see a working version, check out an example of a provider class here.
Heads up! Make sure your provider's class is unique (rename it if you used an example). In Objective-C, there may only have one class for a name. If any other classes exist with that name, your provider will crash the system.
When ShortLook asks you for a photo, you first return an object called an Offer (if you don't want to provide for a notification, return nil
). This offer is simple: you provide the photo identifier, and then set a block that will be called if ShortLook needs your provider. A parameter on this block you set is an object called a Promise. While this promise doesn't directly contain your image at first, it eventually will be used to contain one by your provider. It is, in most basic terms, a promise to provide a contact photo. Since most provider's images will take a while to get (network requests, etc.), this is necessary to ensure optimal performance.
You initialize your offer with a photo identifier, which is a unique string for the contact photo you will provide, for internal use by ShortLook (such as caching, or choosing when to display the image). For the system contact photo provider, this identifier is the phone number or email address of the notification. For a provider like Twitter, it is the URL of the profile photo. For another social network, you may opt to use the photo's account's screen name, it that's more appropriate. Whatever your identifier be, just ensure it represents the photo you will return uniquely.
Once you have initialized your offer object, you can add a resolver using fulfillWithBlock:
. The block you provide here should contain every next operation for grabbing the contact photo, such as network requests. Once you have received your image, pass it back to ShortLook by calling resolveWithImage:
on your promise, which is a parameter of your block. If an error occurs and you are not able to fetch a contact photo for the user, call reject
on the promise. Once you've resolved or rejected a promise, you may not do so it again, such as to change the image.
The promise object also features many properties, such as usesCaching
and backgroundColor
, which can be set at any time before the promise is completed.
If your image is returned instantly, rather than by using a network request, you can use a convenience method on DDNotificationContactPhotoPromiseOffer
, named offerInstantlyResolvingPromiseWithPhotoIdentifier:image:
. Just return the generated promise from your provider. Choose wisely, though. This method should only be used if you can get your image absolutely instantly. If you take too long using this synchronous method, ShortLook may penalize your provider.
- Your package should usually be called something like "APP Photo Provider for ShortLook" in Cydia.
- It is recommended you make your bundle name something like "ShortLook-APP".
You can view the full class documentation for ShortLook's photo provider API here.
You can look at the following open source provider examples to get an idea of how to use the ShortLook API:
Starting in version 1.0.2, ShortLook provides an external coordination API for non-Dynastic tweaks to use. It will allow these tweaks to provide the screen’s display on state, since some tweaks fake the screen being off on OLED phones.
If your tweak keeps the screen on while the user would expect it to be off, ShortLook can obey this preference and behave like the screen is off.
First, implement the following provider in a class where you wish to provide this information:
@protocol DDLunarScreenStateProvider <NSObject>
@required
/// If your tweak keeps the screen awake to provide an always-on experience but should act to Lunar like the display is off, return whether you want the screen to be treated as on or off here. If any single provider is returning NO for this, the screen will be treated as such.
- (BOOL)isScreenOn;
@end
Once you have implemented that, you must register an instance of this class using DDLunarScreenStateManager
. You can call registerScreenStateProvider:
on the shared manager to tell ShortLook to ask your provider before deciding how to treat the screen state, using the following header:
@interface DDLunarScreenStateManager: NSObject
+ (instancetype)sharedManager;
- (void)registerScreenStateProvider:(NSObject<DDLunarScreenStateProvider> *)provider;
- (void)deregisterScreenStateProvider:(NSObject<DDLunarScreenStateProvider> *)provider;
@end
Do not check for the presence of ShortLook by checking the filesystem or other classes. You can directly check that DDLunarScreenStateManager
exists. ShortLook will hold a strong reference to your screen state provider until it is deregistered.
if (NSClassFromString(@"DDLunarScreenStateManager")) {
MyScreenStateProvider *provider = [MyScreenStateProvider new];
[[%c(DDLunarScreenStateManager) sharedManager] registerScreenStateProvider:provider];
}