A modern AppList alternative

Related tags

Database AltList
Overview

AltList

A modern AppList alternative

The main focus of this dependency is to be an easy to use and easy to customize framework to handle per app preferences. Unlike AppLists ALApplicationList class, AltList does not have a way to get installed applications yourself, as stock iOS classes like LSApplicationWorkspace and LSApplicationProxy (MobileCoreService / CoreServices framework) can already do that. Communication to SpringBoard is not needed for this.

Example uses:

// get LSApplicationProxy of all installed applications
NSArray<LSApplicationProxy*>* allInstalledApplications = [[LSApplicationWorkspace defaultWorkspace] allInstalledApplications];

// get LSApplicationProxy for one application
LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:@"com.yourapp.yourapp"];

Features

  • Uses LSApplicationWorkspace, not dependent on RocketBootstrap / SpringBoard injection
  • Supports search bars
  • Supports application sections (similar to AppList)
  • Supports alphabetic indexing if only one section is specified
  • Doesn't reinvent the wheel
  • Supports iOS 9 and up

Installation

Run install_to_theos.sh and add it to the makefile of your project:

<YOUR_PROJECT>_EXTRA_FRAMEWORKS = AltList

Then you can import it using #import <AltList/AltList.h> or just use the classes below in your preferences plist.

Documentation

AltList features three PSListController subclasses that can be used from your preference bundle or application. Unlike AppList it is highly customizable, so if you want to adapt something you can just make a subclass and specify that instead.

All classes can be configured via values in your plist.

ATLApplicationSection

Just like the original AppList, AltList allows you to specify the sections of applications it should display.

AltList ships with a few stock section types:

  • All: All Applications, including hidden ones
  • System: System Applications (e.g. App Store, Safari)
  • User: User installed applications (e.g. Reddit, Instagram)
  • Hidden: Hidden applications (e.g. InCallService, Carplay Settings)
  • Visible: All applications that are not hidden (e.g. System and User applications)

The stock section types already have predicates and localized names. Custom sections are also supported and allow you to specify your own section name and predicate. If you want your custom section name to be localized: the value you set will be passed to the localizedStringForString of your ListController (see below).

Key Type Fallback Usage
sectionType String (All/System/User/Hidden/Visible/Custom) Visible Type of the section, see above
sectionName String @"" For custom sections, name of the section
sectionPredicate String @"" For custom sections, predicate to filter the applications, check out the LSApplicationProxy headers for possible values to use
customClass String @"" Custom subclass of ATLApplicationSection to use, in case you want to implement even more custom behaviour

ATLApplicationListControllerBase

ATLApplicationListControllerBase is the base class inherited by the other classes, it has several features that apply to all classes below.

Keys

Key Type Fallback Usage
sections Array One Visible section Array of dictionaries that represent the sections in which the applications are shown
useSearchBar Boolean false Whether there should be a search bar at the top that allows to search for applications (Example)
hideSearchBarWhileScrolling Boolean false When useSearchBar is enabled, whether the search bar should be hidden while scrolling (Always true on iOS 10 and below) (Example)
showIdentifiersAsSubtitle Boolean false Whether the application identifiers should be shown in the subtitle (note: implemented by subclasses) (Example)
alphabeticIndexingEnabled Boolean false When there is only one section, whether to section and index it by the starting letters (Example)
hideAlphabeticSectionHeaders Boolean false When alphabeticIndexingEnabled is true, whether to hide the sections that contain the first letters (Example)
localizationBundlePath String @"" Path to the bundle that should be used for localizing custom section titles

Methods (Can be subclassed for customization)

Method Purpose
- (void)loadPreferences Load the preference value that the list controller will display
- (void)prepareForPopulatingSections Initialize stuff that needs to be done before the populating starts
- (NSString*)localizedStringForString:(NSString*)string Localize string if possible from internal AltList bundle or the localization bundle specified by localizationBundlePath
- (void)reloadApplications Reload applications and specifiers
- (BOOL)shouldHideApplicationSpecifiers Whether any specifier at all should be hidden (internally used for search bar)
- (BOOL)shouldHideApplicationSpecifier:(PSSpecifier*)specifier Whether the specifier specifier should be hidden (internally used for search bar)
- (PSSpecifier*)createSpecifierForApplicationProxy:(LSApplicationProxy*)applicationProxy Create a specifier for the application represented by applicationProxy
- (NSArray*)createSpecifiersForApplicationSection:(ATLApplicationSection*)section Create the specicifers for a whole application section represented by section (Calls the method above)

ATLApplicationListSelectionController

ATLApplicationListSelectionController can be used as the detail class of a PSLinkListCell to have a list of applications of which one can be selected. The selected applications bundle identifier will be saved in the preference domain specified via defaults under the specified key. It respects the get / set attributes so by default it will use the readPreferenceValue and setPreferenceValue:specifier: methods of the PSListController that contains the cell for reading / writing the value. Setting the cellClass to ATLApplicationSelectionCell is recommended so the value preview shows the application name instead of the application bundle identifier.

Example

<dict>
	<key>cell</key>
	<string>PSLinkListCell</string>
	<key>detail</key>
	<string>ATLApplicationListSelectionController</string>
	<key>cellClass</key>
	<string>ATLApplicationSelectionCell</string>
	<key>defaults</key>
	<string>com.yourcompany.yourtweakprefs</string>
	<key>key</key>
	<string>(...)</string>
	<key>label</key>
	<string>(...)</string>
	<key>sections</key>
	<array>
		<dict>
			<key>sectionType</key>
			<string>System</string>
		</dict>
		<dict>
			<key>sectionType</key>
			<string>User</string>
		</dict>
	</array>
	<key>useSearchBar</key>
	<true/>
	<key>hideSearchBarWhileScrolling</key>
	<false/>
</dict>

ATLApplicationListMultiSelectionController

ATLApplicationListSelectionController can be used as the detail class of a PSLinkListCell to have a list of applications where each has a switch next to it. The key defaultApplicationSwitchValue can be set to a boolean and will be used as the default value of the application switches. An array with the application identifiers of the enabled (or disabled when defaultApplicationSwitchValue is true) applications will be saved in the preference domain specified via defaults under the specified key. It respects the get / set attributes so by default it will use the readPreferenceValue and setPreferenceValue:specifier: methods of the PSListController that contains the cell for reading / writing the value.

Keys

Key Type Fallback Usage
defaultApplicationSwitchValue Boolean false Default value of the application switches

Example

<dict>
	<key>cell</key>
	<string>PSLinkListCell</string>
	<key>detail</key>
	<string>ATLApplicationListMultiSelectionController</string>
	<key>defaults</key>
	<string>(...)</string>
	<key>key</key>
	<string>(...)</string>
	<key>label</key>
	<string>(...)</string>
	<key>sections</key>
	<array>
		<dict>
			<key>sectionType</key>
			<string>Visible</string>
		</dict>
		<dict>
			<key>sectionType</key>
			<string>Hidden</string>
		</dict>
	</array>
	<key>showIdentifiersAsSubtitle</key>
	<true/>
	<key>defaultApplicationSwitchValue</key>
	<false/>
	<key>useSearchBar</key>
	<true/>
</dict>

ATLApplicationListSubcontrollerController

ATLApplicationListSubcontrollerController can be used as the detail class of a PSLinkListCell to have one PSListController per application. The key subcontrollerClass is used to specify the PSListController subclass, although you can also subclass ATLApplicationListSubcontroller instead which has a convienience method to get the application identifier and also automatically reloads the preview string shown in the application list. Preview strings are supported but require you to subclass ATLApplicationListSubcontrollerController and use your subclass instead. In your subclass you need to overwrite the previewStringForApplicationWithIdentifier: method and return the preview string there. Preferences also need to be handled in your PSListController/ATLApplicationListSubcontrollerController subclass, if you want an example for this, check out the Choicy preferences.

Keys

Key Type Fallback Usage
subcontrollerClass String None (Required) Name of the class that should be used for the application subpages

Example

<dict>
	<key>cell</key>
	<string>PSLinkListCell</string>
	<key>detail</key>
	<string>ATLApplicationListSubcontrollerController</string>
	<key>subcontrollerClass</key>
	<string>(...)</string>
	<key>label</key>
	<string>(...)</string>
	<key>sections</key>
	<array>
		<dict>
			<key>sectionType</key>
			<string>Visible</string>
		</dict>
		<dict>
			<key>sectionType</key>
			<string>Hidden</string>
		</dict>
	</array>
	<key>showIdentifiersAsSubtitle</key>
	<true/>
	<key>defaultApplicationSwitchValue</key>
	<false/>
	<key>useSearchBar</key>
	<true/>
</dict>
Issues
  • Cannot install to theos

    Cannot install to theos

    This is the output I get when I run ./install_to_theos.sh

    `==> Cleaning…

    Making clean in AltListTestBundle… ==> Cleaning… Making all for framework AltList… ==> Copying resource directories into the framework wrapper… ==> Copying public headers into the framework wrapper… ==> Preprocessing AltList.x… ==> Preprocessing AltList.x… ==> Compiling ATLApplicationListControllerBase.m (armv7)… ATLApplicationListControllerBase.m:14:6: error: comparison of function 'dispatch_queue_attr_make_with_qos_class' not equal to a null pointer is always true [-Werror,-Wtautological-pointer-compare] if (dispatch_queue_attr_make_with_qos_class != NULL) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~ ATLApplicationListControllerBase.m:14:6: note: prefix with the address-of operator to silence this warning if (dispatch_queue_attr_make_with_qos_class != NULL) ^ & 1 error generated. make[3]: *** [/home/atrt7/theos/makefiles/instance/rules.mk:193: /home/atrt7/AltList/.theos/obj/armv7/ATLApplicationListControllerBase.m.9349dfb3.o] Error 1 make[3]: *** Waiting for unfinished jobs.... ==> Compiling ATLApplicationListControllerBase.m (arm64)… ATLApplicationListControllerBase.m:14:6: error: comparison of function 'dispatch_queue_attr_make_with_qos_class' not equal to a null pointer is always true [-Werror,-Wtautological-pointer-compare] if (dispatch_queue_attr_make_with_qos_class != NULL) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~ ATLApplicationListControllerBase.m:14:6: note: prefix with the address-of operator to silence this warning if (dispatch_queue_attr_make_with_qos_class != NULL) ^ & 1 error generated. make[3]: *** [/home/atrt7/theos/makefiles/instance/rules.mk:193: /home/atrt7/AltList/.theos/obj/arm64/ATLApplicationListControllerBase.m.2699f159.o] Error 1 make[3]: *** Waiting for unfinished jobs.... ==> Compiling ATLApplicationListMultiSelectionController.m (armv7)… rm /home/atrt7/AltList/.theos/obj/armv7/AltList.x.m make[2]: *** [/home/atrt7/theos/makefiles/instance/framework.mk:36: /home/atrt7/AltList/.theos/obj/armv7/AltList.framework/AltList] Error 2 make[2]: *** Waiting for unfinished jobs.... ==> Compiling ATLApplicationListMultiSelectionController.m (arm64)… ==> Compiling ATLApplicationListSelectionController.m (arm64)… rm /home/atrt7/AltList/.theos/obj/arm64/AltList.x.m make[2]: *** [/home/atrt7/theos/makefiles/instance/framework.mk:36: /home/atrt7/AltList/.theos/obj/arm64/AltList.framework/AltList] Error 2 make[1]: *** [/home/atrt7/theos/makefiles/instance/framework.mk:27: internal-framework-all_] Error 2 make: *** [/home/atrt7/theos/makefiles/master/rules.mk:117: AltList.all.framework.variables] Error 2`

    opened by atrt7 9
  • AltList 1.0.5-2 crash

    AltList 1.0.5-2 crash

    iOS Settings crashes when I tried to open any preference which have com.opa334.altlist dependencies, such as: Crane, Bakgrunnur, bfdecrypt.

    Crash log: https://pastebin.com/aaRegR5L

    💥 AltList versions that crash: 1.0.1, 1.0.2, 1.0.3, 1.0.4, 1.0.5-2 ✅ Worked fine with AltList 1.0-1

    Device: iPhone 12 Pro Max iOS: 14.3 Jailbreak: Taurine 1.0.4

    opened by sadalhayat 5
  • Basic Support for iOS 8/7

    Basic Support for iOS 8/7

    Tested on 14.3, 12.4, 8.4.1, 7.1.2.

    opened by brendonjkding 4
  • ar.Localization

    ar.Localization

    "Applications" = "التطبيقات"; "System Applications" = "تطبيقات النظام"; "User Applications" = "تطبيقات المستخدم"; "Hidden Applications" = "التطبيقات المخفية

    opened by ammaripa 1
  • Feature request: Ability to search bundleId

    Feature request: Ability to search bundleId

    In some cases(eg. Chinese name), searching bundleId is faster than names. It would be handy if there is a key in preference plist to enable the ability to search names and Ids simultaneously.

    opened by brendonjkding 1
  • Feature request: Bundleless approach for using AltList

    Feature request: Bundleless approach for using AltList

    Seen from the example AltList project, there’s still the need to build s bundle that does nothing more than loading the Root plist. Just like AppList, it would be handy if we can plug bundle and isController properties and everything in one plist. AltList.bundle should be created or symlinked to /System/Library/PreferenceBundles, to start the matter.

    opened by PoomSmart 1
  •  Turkish language file tr.strings

    Turkish language file tr.strings

    "Applications" = "Uygulamalar"; "System Applications" = "Sistem Uygulamaları"; "User Applications" = "Kullanıcı Uygulamaları"; "Hidden Applications" = "Gizlenmiş Uygulamalar";

    opened by serif61 0
  • Linker Error

    Linker Error

    I fixed the compilation issues by doing #import <Foundation/Foundation.h> in some files. now I get a linker error

    Undefined symbols for architecture armv7:
      "___isOSVersionAtLeast", referenced from:
          -[ATLApplicationListControllerBase _setUpSearchBar] in ATLApplicationListControllerBase.m.ee6620ba.o
          -[ATLApplicationSubtitleCell initWithStyle:reuseIdentifier:specifier:] in ATLApplicationSubtitleCell.m.ee6620ba.o
    ld: symbol(s) not found for architecture armv7
    clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
    make[3]: *** [/home/atrt7/theos/makefiles/instance/framework.mk:36: /home/atrt7/AltList/.theos/obj/armv7/AltList.framework/AltList] Error 1
    rm /home/atrt7/AltList/.theos/obj/armv7/AltList.x.m
    make[2]: *** [/home/atrt7/theos/makefiles/instance/framework.mk:36: /home/atrt7/AltList/.theos/obj/armv7/AltList.framework/AltList] Error 2
    make[2]: *** Waiting for unfinished jobs....
    ==> Linking framework AltList (arm64)…
    ==> Generating debug symbols for AltList…
    ==> Stripping AltList (arm64)…
    rm /home/atrt7/AltList/.theos/obj/arm64/AltList.x.m
    make[1]: *** [/home/atrt7/theos/makefiles/instance/framework.mk:27: internal-framework-all_] Error 2
    make: *** [/home/atrt7/theos/makefiles/master/rules.mk:117: AltList.all.framework.variables] Error 2```
    opened by atrt7 4
Owner
Lars Fröder
Lars Fröder
An alternative to Core Data for people who like having direct SQL access.

FCModel 2 An alternative to Core Data for people who like having direct SQL access. By Marco Arment. See the LICENSE file for license info (it's the M

null 1.7k Nov 29, 2021
Modern Swift API for NSUserDefaults

SwiftyUserDefaults Modern Swift API for NSUserDefaults SwiftyUserDefaults makes user defaults enjoyable to use by combining expressive Swifty API with

Luke 4.5k Nov 29, 2021
Swifty and modern UserDefaults

Defaults Swifty and modern UserDefaults Store key-value pairs persistently across launches of your app. It uses NSUserDefaults underneath but exposes

Sindre Sorhus 921 Nov 26, 2021
Modern interface to UserDefaults + Codable support

Default Modern interface to UserDefaults + Codable support What is Default? Default is a library that extends what UserDefaults can do by providing ex

Nicholas Maccharoli 465 Nov 23, 2021
A WeChat alternative. Written in Swift 5.

TSWeChat - A WeChat alternative, updated to Swift 5. 中文说明 Requirements Cocoapods 1.2.0 + iOS 10.0+ / Mac OS X 10.9+ Xcode 10.0+ Features Send your ric

Hilen Lai 3.7k Nov 26, 2021
A collaborative list of Parse alternative backend service providers.

Parse alternatives As you may noticed, Parse will be fully retired after a year-long period ending on January 28, 2017. Most of us need to find an alt

Related Code 2.8k Nov 24, 2021
An alternative to Core Data for people who like having direct SQL access.

FCModel 2 An alternative to Core Data for people who like having direct SQL access. By Marco Arment. See the LICENSE file for license info (it's the M

null 1.7k Nov 29, 2021
Schedule timing task in Swift using a fluent API. (A friendly alternative to Timer)

Schedule(简体中文) Schedule is a timing tasks scheduler written in Swift. It allows you run timing tasks with elegant and intuitive syntax. Features Elega

Luo Xiu 1.7k Nov 30, 2021
Git Submodule Alternative for Cocoa.

CocoaSeeds Git Submodule Alternative for Cocoa. Inspired by CocoaPods. Why? iOS 7 projects do not support the use of Swift libraries from CocoaPods or

Suyeol Jeon 343 Oct 1, 2021
An alternative layout framework, a balanced medium between manual layout and auto layout. Great for calculating frames with FlightAnimator!!

FlightLayout Introduction FlightLayout is a light weight, and easy to learn layout framework as an extension of the UIView. Functionally, it lives som

Anton 23 Nov 20, 2020
Eugene Kazaev 345 Nov 29, 2021
An alternative to UIStackView for common Auto Layout patterns.

StackLayout StackLayout builds on Auto Layout to make some of the most common layouts easier to manage. It creates the constraints that you need and a

Bridger Maxwell 78 Jul 17, 2020
iOS / Objective C: an extremely simple UIAlertView alternative

RKDropdownAlert an extremely simple (and customizeable) alert alternative based on Facebook's app Slingshot, and inspiration from SVProgressHUD (yes,

Richard Kim 1.6k Nov 15, 2021
🔸 A customizable alternative to UIPickerView in Swift.

PickerView PickerView is an easy to use and customize alternative to UIPickerView written in Swift. It was developed to provide a highly customizable

Filipe Alvarenga 454 Nov 24, 2021
An elegant alternative to the UIStepper written in Swift

An elegant alternative to the UIStepper in Swift with a thumb slider addition to control the value update with more flexibility. Usage let stepper = S

Yannick Loriot 421 Nov 18, 2021
Nicely animated flat design switch alternative to UISwitch

AIFlatSwitch A smooth, nice looking and IBDesignable flat design switch for iOS. Can be used instead of UISwitch. Inspired by Creativedash's Dribbble

null 919 Nov 17, 2021
● ○ ○ ○ A nice, animated UIPageControl alternative.

Page Control Installation Usage Example import UIKit import PageControl class ViewController: UIViewController, UIScrollViewDelegate { @IBOu

Kasper Lahti 109 Nov 26, 2021
💥 Beautiful, animated and highly customizable UIPageControl alternative for iOS.

PageControl Requirements iOS 9.0+ Xcode 7.0+ Installation CocoaPods: Add folowing line to Podfile and run 'pod instal'. pod 'Sevruk-PageControl' Or j

Sevruk Development 29 Nov 22, 2021
📱 A minimal tab bar alternative

MiniTabBar A clean simple alternative to the UITabBar. Only shows the title when being tapped on. Gives the app a way cleaner look :) Requirements iOS

Dylan Marriott 152 Nov 26, 2021
Git Submodule Alternative for Cocoa.

CocoaSeeds Git Submodule Alternative for Cocoa. Inspired by CocoaPods. Why? iOS 7 projects do not support the use of Swift libraries from CocoaPods or

Suyeol Jeon 343 Oct 1, 2021
Schedule timing task in Swift using a fluent API. (A friendly alternative to Timer)

Schedule(简体中文) Schedule is a timing tasks scheduler written in Swift. It allows you run timing tasks with elegant and intuitive syntax. Features Elega

Luo Xiu 1.7k Nov 30, 2021
MZFormSheetPresentationController provides an alternative to the native iOS UIModalPresentationFormSheet, adding support for iPhone and additional opportunities to setup UIPresentationController size and feel form sheet.

MZFormSheetPresentationController MZFormSheetPresentationController provides an alternative to the native iOS UIModalPresentationFormSheet, adding sup

Michał Zaborowski 977 Nov 23, 2021
🔄 GravitySlider is a beautiful alternative to the standard UICollectionView flow layout.

GravitySliderFlowLayout Made by Applikey Solutions Find this project on Dribbble Table of Contents Purpose Supported OS & SDK Versions Installation Us

Applikey Solutions 850 Nov 21, 2021
🔄 GravitySlider is a beautiful alternative to the standard UICollectionView flow layout.

GravitySliderFlowLayout Made by Applikey Solutions Find this project on Dribbble Table of Contents Purpose Supported OS & SDK Versions Installation Us

Applikey Solutions 849 Nov 26, 2021
Modern, type-safe API for building animations on iOS

Stagehand Stagehand provides a modern, type-safe API for building animations on iOS. Stagehand is designed around a set of core ideas: Composition of

Cash App 113 Nov 24, 2021
A modern Swift wrapper for Instagram Private API.

Swiftagram is a wrapper for Instagram Private API, written entirely in (modern) Swift. Instagram's official APIs, both the Instagram Basic Display API

Stefano Bertagno 164 Nov 28, 2021
Modern Concurrency and Synchronization for Swift.

##Features Simple Atomic<T> class for numbers and strings. Uncomplicated dispatch keyword for firing off background routines. Awesome Chan<T> for conc

Josh Baker 421 Jul 13, 2021
Modern Swift API for NSUserDefaults

SwiftyUserDefaults Modern Swift API for NSUserDefaults SwiftyUserDefaults makes user defaults enjoyable to use by combining expressive Swifty API with

Luke 4.5k Nov 29, 2021
Swifty and modern UserDefaults

Defaults Swifty and modern UserDefaults Store key-value pairs persistently across launches of your app. It uses NSUserDefaults underneath but exposes

Sindre Sorhus 921 Nov 26, 2021