### Shell Compilation and Execution
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
This transcript shows the commands to compile and run the Objective-C example, demonstrating the output of the match enumerator.
```shell
shell% cd examples
shell% gcc -I.. -g -o main main.m RKLMatchEnumerator.m ../RegexKitLite.m -framework Foundation -licucore
shell% ./main
2008-03-21 15:56:17.469 main[44050:807] searchString: 'one
two
four
'
2008-03-21 15:56:17.520 main[44050:807] regexString : '(?m)^.*$'
2008-03-21 15:56:17.575 main[44050:807] 1: 3 'one'
2008-03-21 15:56:17.580 main[44050:807] 2: 3 'two'
2008-03-21 15:56:17.584 main[44050:807] 3: 0 ''
2008-03-21 15:56:17.590 main[44050:807] 4: 4 'four'
shell% ▌
```
--------------------------------
### Define OS and Disk Space Installation Requirements
Source: https://context7.com/packagesdev/packages/llms.txt
Configure OS version and disk space requirements for installer pre-flight checks. Localized failure messages can be attached.
```objc
#import "PKGRequirement.h"
#import "PKGRequirementFailureMessage.h"
// ── OS version requirement ────────────────────────────────────────────────────
PKGRequirement *osReq = [[PKGRequirement alloc] init];
osReq.enabled = YES;
osReq.name = @"OS Version Check";
osReq.identifier = @"fr.whitebox.requirements.os";
osReq.type = PKGRequirementTypeInstallation;
osReq.failureBehavior = PKGRequirementOnFailureBehaviorInstallationStop;
// Plug in settings for the OS requirement plugin
osReq.settingsRepresentation = @{
@"OS_TARGET_DISK" : @(PKGRequirementOSTargetStartupDisk),
@"OS_DISTRIBUTION" : @(PKGRequirementOSDistributionClient),
@"OS_MINIMUM_VERSION": @(101500), // 10.15 Catalina
@"OS_MAXIMUM_VERSION": @(0) // no upper bound
};
// Localized failure messages
PKGRequirementFailureMessage *msg = [[PKGRequirementFailureMessage alloc] init];
msg.messageTitle = @"Unsupported macOS Version";
msg.messageDescription = @"This installer requires macOS 10.15 or later.";
osReq.messages[@"en"] = [msg representation];
// ── Disk space requirement ────────────────────────────────────────────────────
PKGRequirement *diskReq = [[PKGRequirement alloc] init];
diskReq.enabled = YES;
diskReq.identifier = @"fr.whitebox.requirements.diskspace";
diskReq.type = PKGRequirementTypeTarget;
diskReq.failureBehavior = PKGRequirementOnFailureBehaviorInstallationWarning;
diskReq.settingsRepresentation = @{
@"DISK_SPACE_MINIMUM_SIZE_VALUE": @(2),
@"DISK_SPACE_MINIMUM_SIZE_UNIT" : @(PKGRequirementDiskSpaceSizeUnitGB)
};
// Attach requirements to a distribution project
PKGDistributionProjectRequirementsAndResources *rr = dist.requirementsAndResources;
[rr.requirements addObject:osReq];
[rr.requirements addObject:diskReq];
```
--------------------------------
### Manage .pkgproj Files with packagesutil (Get)
Source: https://context7.com/packagesdev/packages/llms.txt
Use `packagesutil` with the `get` verb to retrieve project-level and package-level properties from `.pkgproj` files without opening the GUI. This is useful for scripting and automation.
```sh
packagesutil --file MyApp.pkgproj get project name
```
```sh
packagesutil --file MyApp.pkgproj get project build-folder
```
```sh
packagesutil --file MyApp.pkgproj get project build-format
```
```sh
packagesutil --file MyApp.pkgproj get package identifier
```
```sh
packagesutil --file MyApp.pkgproj get package version
```
```sh
packagesutil --file MyApp.pkgproj get package post-installation-behavior
```
```sh
packagesutil --file MyApp.pkgproj get package pre-installation-script
```
--------------------------------
### PKGPackageScriptsAndResources
Source: https://context7.com/packagesdev/packages/llms.txt
Associates pre-installation and post-installation scripts with a package, along with any bundled resources needed at install time.
```APIDOC
## Pre/Post Install Scripts
PKGPackageScriptsAndResources *scripts = [[PKGPackageScriptsAndResources alloc] init];
// Pre-install script (absolute path)
scripts.preInstallationScriptPath =
[PKGFilePath filePathWithAbsolutePath:@"/scripts/preinstall.sh"];
// Post-install script (relative to project)
scripts.postInstallationScriptPath =
[PKGFilePath filePathWithString:@"scripts/postinstall.sh"
type:PKGFilePathTypeRelativeToProject];
// Attach to a component
PKGPackageComponent *comp = [PKGPackageComponent projectComponent];
comp.scriptsAndResources = scripts;
// Inspect
NSLog(@"Pre: %@", comp.scriptsAndResources.preInstallationScriptPath.string);
NSLog(@"Post: %@", comp.scriptsAndResources.postInstallationScriptPath.string);
```
--------------------------------
### Create PKGFileItem for New Folder
Source: https://context7.com/packagesdev/packages/llms.txt
Use PKGFileItem to represent a new folder created during installation. Specify its name, owner (uid), group (gid), and permissions.
```objc
#import "PKGFileItem.h"
#import "PKGFilePath.h"
// ── New folder created by the installer ──────────────────────────────────────
PKGFileItem *appFolder = [PKGFileItem newFolderWithName:@"MyApp"
uid:0 // root
gid:80 // admin
permissions:0755];
```
--------------------------------
### PKGFileItem
Source: https://context7.com/packagesdev/packages/llms.txt
Represents a single entry (file, folder template, or new folder) in the installer payload hierarchy, along with its ownership and permissions.
```APIDOC
## Model API: `PKGFileItem` — Payload File System Entries
Represents a single entry (file, folder template, or new folder) in the installer payload hierarchy, along with its ownership and permissions.
```objc
#import "PKGFileItem.h"
#import "PKGFilePath.h"
// ── New folder created by the installer ──────────────────────────────────────
PKGFileItem *appFolder = [PKGFileItem newFolderWithName:@"MyApp"
uid:0 // root
gid:80 // admin
permissions:0755];
// ── Folder template (mirrors a pre-existing directory) ───────────────────────
PKGFileItem *libFolder = [PKGFileItem folderTemplateWithName:@"Application Support"
uid:0
gid:80
permissions:0755];
// ── File system item sourced from disk ───────────────────────────────────────
PKGFilePath *srcPath = [PKGFilePath filePathWithAbsolutePath:@"/build/MyApp.app"];
PKGFileItem *appItem = [PKGFileItem fileSystemItemWithFilePath:srcPath
uid:0
gid:80
permissions:0755];
// ── Elastic folder (auto-expands during installation) ────────────────────────
PKGFileItem *elastic = [PKGFileItem newElasticFolderWithName:@"Plugins"
uid:0
gid:80
permissions:0755];
// Payload file name (name inside the installed package)
appItem.payloadFileName = @"MyApplication.app";
// Inspect type
NSLog(@"Is file system item: %d",
appItem.type == PKGFileItemTypeFileSystemItem); // → 1
```
```
--------------------------------
### PKGPackageSettings - Per-Package Metadata
Source: https://context7.com/packagesdev/packages/llms.txt
Explains how to configure metadata for a single package component, including basic information, installation behavior, authorization, and payload options.
```APIDOC
## Basic metadata
settings.name = @"MyApplication";
settings.identifier = @"com.acme.myapp";
settings.version = @"3.2.1";
## Post-install behavior
settings.conclusionAction = PKGPackageConclusionActionRequireRestart;
## Authorization
settings.authenticationMode = PKGPackageAuthenticationRoot;
## Payload options
settings.relocatable = NO;
settings.overwriteDirectoryPermissions = YES;
settings.followSymbolicLinks = NO;
settings.useHFSPlusCompression = YES;
## Package location (embedded in distribution)
settings.locationType = PKGPackageLocationEmbedded;
## Package location (external HTTP URL)
settings.locationType = PKGPackageLocationHTTPSURL;
settings.locationURL = @"https://cdn.acme.com/packages/myapp-3.2.1.pkg";
## Derived helpers
NSString *scheme = [settings locationScheme]; // → @"https"
NSString *path = [settings locationPath]; // → @"//cdn.acme.com/packages/myapp-3.2.1.pkg"
## Serialize to / from representation
NSMutableDictionary *rep = [settings representation];
PKGPackageSettings *restored = [[PKGPackageSettings alloc] initWithRepresentation:rep error:nil];
NSLog(@"%@ %@", restored.identifier, restored.version);
// → com.acme.myapp 3.2.1
```
--------------------------------
### PKGDistributionProject
Source: https://context7.com/packagesdev/packages/llms.txt
Manages a collection of PKGPackageComponent objects along with presentation settings and installation requirements.
```APIDOC
## Load an existing distribution project
NSError *error = nil;
PKGDistributionProject *dist = (PKGDistributionProject *)
[PKGProject projectWithContentsOfFile:@"/Projects/Suite.pkgproj" error:&error];
PKGDistributionProjectSettings *settings = (PKGDistributionProjectSettings *)dist.settings;
settings.buildFormat = PKGProjectBuildFormatFlat;
settings.name = @"ACME Suite Installer";
## Iterate package components
for (PKGPackageComponent *comp in dist.packageComponents) {
NSLog(@"UUID: %@ type: %lu name: %@",
comp.UUID,
(unsigned long)comp.type,
comp.packageSettings.name);
}
## Look up a component
PKGPackageComponent *comp = [dist packageComponentWithIdentifier:@"com.acme.framework"];
NSLog(@"Found: %@", comp.packageSettings.name);
## Add a new project component
PKGPackageComponent *newComp = [PKGPackageComponent projectComponent];
newComp.packageSettings.name = @"ACME Helper";
newComp.packageSettings.identifier = @"com.acme.helper";
newComp.packageSettings.version = @"1.0.0";
[dist.packageComponents addObject:newComp];
## Check whether it is flat
NSLog(@"Flat: %d", dist.isFlat); // → 1
## Save
[dist writeToFile:@"/Projects/Suite.pkgproj" atomically:YES];
```
--------------------------------
### Configure Package Payload
Source: https://context7.com/packagesdev/packages/llms.txt
Create and configure package payloads. Use `PKGPackagePayload.emptyPayload` for a new payload or `initWithDefaultHierarchy:error:` to initialize with a structure. The install location can also be extracted from raw XML data.
```objc
#import "PKGPackagePayload.h"
#import "PKGPayloadTree.h"
// ── Create an empty payload ───────────────────────────────────────────────────
PKGPackagePayload *payload = [PKGPackagePayload emptyPayload];
payload.defaultInstallLocation = @"/";
payload.type = PKGPayloadInternal;
payload.splitForksIfNeeded = NO;
payload.preserveExtendedAttributes = YES;
payload.hiddenFolderTemplatesIncluded = YES;
payload.treatMissingPayloadFilesAsWarnings = NO;
// ── Create with a default hierarchy ─────────────────────────────────────────
NSDictionary *defaultHierarchy = @{
@"PATH": @"Applications",
@"PATH_TYPE": @0,
@"TYPE": @1,
@"GID": @80,
@"UID": @0,
@"PERMISSIONS": @493,
@"CHILDREN": @[]
};
NSError *err = nil;
PKGPackagePayload *withHierarchy =
[[PKGPackagePayload alloc] initWithDefaultHierarchy:defaultHierarchy error:&err];
// ── Extract install location from raw XML data ───────────────────────────────
NSData *packageInfoXML = /* raw PackageInfo XML bytes from an existing .pkg */ nil;
NSString *loc = [PKGPackagePayload installLocationWithXMLData:packageInfoXML];
NSLog(@"Install location: %@", loc); // → /
// ── Attach to a package component ────────────────────────────────────────────
PKGPackageComponent *comp = [PKGPackageComponent projectComponent];
comp.payload = payload;
```
--------------------------------
### PKGPackagePayload
Source: https://context7.com/packagesdev/packages/llms.txt
Configures the payload root tree, default install location, and various payload-level options for a single package.
```APIDOC
## Create an empty payload
PKGPackagePayload *payload = [PKGPackagePayload emptyPayload];
payload.defaultInstallLocation = @"/";
payload.type = PKGPayloadInternal;
payload.splitForksIfNeeded = NO;
payload.preserveExtendedAttributes = YES;
payload.hiddenFolderTemplatesIncluded = YES;
payload.treatMissingPayloadFilesAsWarnings = NO;
## Create with a default hierarchy
NSDictionary *defaultHierarchy = @{
@"PATH": @"Applications",
@"PATH_TYPE": @0,
@"TYPE": @1,
@"GID": @80,
@"UID": @0,
@"PERMISSIONS": @493,
@"CHILDREN": @[]
};
NSError *err = nil;
PKGPackagePayload *withHierarchy = [[PKGPackagePayload alloc] initWithDefaultHierarchy:defaultHierarchy error:&err];
## Extract install location from raw XML data
NSData *packageInfoXML = /* raw PackageInfo XML bytes from an existing .pkg */ nil;
NSString *loc = [PKGPackagePayload installLocationWithXMLData:packageInfoXML];
NSLog(@"Install location: %@", loc); // → /
## Attach to a package component
PKGPackageComponent *comp = [PKGPackageComponent projectComponent];
comp.payload = payload;
```
--------------------------------
### Execute App-Only Build
Source: https://context7.com/packagesdev/packages/llms.txt
Use the `build_app.sh` script to build only the application and its package, omitting the DMG creation step. This is useful for development or when only the installer package is needed.
```sh
cd /path/to/packages-repo/distribution
./build_app.sh
# Same as build.sh but stops after producing Packages.pkg
```
--------------------------------
### Create PKGFileItem for Elastic Folder
Source: https://context7.com/packagesdev/packages/llms.txt
Use PKGFileItem to represent an elastic folder that automatically expands during installation. Specify its name, owner (uid), group (gid), and permissions.
```objc
// ── Elastic folder (auto-expands during installation) ────────────────────────
PKGFileItem *elastic = [PKGFileItem newElasticFolderWithName:@"Plugins"
uid:0
gid:80
permissions:0755];
```
--------------------------------
### PKGCertificatesUtilities - Code-Signing Identity Lookup
Source: https://context7.com/packagesdev/packages/llms.txt
Queries the system keychain for available Developer ID Installer certificates and resolves signing identities for use with `packagesbuild`.
```APIDOC
## PKGCertificatesUtilities
### Description
Queries the system keychain for available Developer ID Installer certificates and resolves signing identities for use with `packagesbuild`.
### Methods
#### `availableIdentities`
Lists all available signing identities.
**Return Value**
An array of strings, where each string is the name of an available signing identity.
**Usage**
```objc
NSArray *identities = [PKGCertificatesUtilities availableIdentities];
for (NSString *name in identities) {
NSLog(@" %@", name);
}
// → Developer ID Installer: ACME Corp (XXXXXXXXXX)
```
#### `identityWithName:atPath:options:error:`
Looks up a specific identity in the system keychain.
**Parameters**
- **name** (NSString *) - The name of the identity to look up.
- **path** (NSString *) - The path to the keychain file. Use `PKGLoginKeychainPath` for the login keychain.
- **options** (PKGCertificateSearchOptions) - Options for searching certificates, e.g., `PKGCertificateSearchNonExpired`.
- **error** (OSStatus *) - A pointer to an `OSStatus` variable to store any error code.
**Return Value**
A `SecIdentityRef` representing the found identity, or `NULL` if an error occurred.
**Usage**
```objc
OSStatus status;
SecIdentityRef identity = [PKGCertificatesUtilities identityWithName:@"Developer ID Installer: ACME Corp"
atPath:PKGLoginKeychainPath
options:PKGCertificateSearchNonExpired
error:&status];
if (identity) {
NSLog(@"Identity found");
CFRelease(identity);
} else {
NSLog(@"Error: %d", (int)status);
}
```
#### `identityWithName:atPath:error:`
Looks up a specific identity using an error code enum for error handling.
**Parameters**
- **name** (NSString *) - The name of the identity to look up.
- **path** (NSString *) - The path to the keychain file.
- **error** (PKGCertificateErrorCode *) - A pointer to a `PKGCertificateErrorCode` variable to store the error.
**Return Value**
A `SecIdentityRef` representing the found identity, or `NULL` if an error occurred.
**Usage**
```objc
PKGCertificateErrorCode errCode;
SecIdentityRef id2 = [PKGCertificatesUtilities identityWithName:@"Developer ID Installer: ACME Corp"
atPath:@"/Users/ci/Library/Keychains/CI.keychain"
error:&errCode];
if (!id2) {
switch (errCode) {
case PKGCertificateErrorMissingCertificate:
NSLog(@"Certificate not found"); break;
case PKGCertificateErrorExpiredCertificate:
NSLog(@"Certificate expired"); break;
case PKGCertificateErrorMissingPrivateKey:
NSLog(@"Private key not found"); break;
}
}
```
#### `copyOfCertificateWithName:isExpired:`
Checks whether a certificate is expired.
**Parameters**
- **name** (NSString *) - The name of the certificate to check.
- **expired** (BOOL *) - A pointer to a boolean variable that will be set to `YES` if the certificate is expired, `NO` otherwise.
**Return Value**
A `SecCertificateRef` representing the certificate, or `NULL` if the certificate is not found.
**Usage**
```objc
BOOL expired = NO;
SecCertificateRef cert = [PKGCertificatesUtilities copyOfCertificateWithName:@"Developer ID Installer: ACME Corp"
isExpired:&expired];
NSLog(@"Expired: %d", expired);
if (cert) CFRelease(cert);
```
```
--------------------------------
### List Available Signing Identities
Source: https://context7.com/packagesdev/packages/llms.txt
Queries the system keychain for all available Developer ID Installer certificates. This is useful for identifying potential signing identities before attempting to use them.
```objc
#import "PKGCertificatesUtilities.h"
// ── List all available signing identities ────────────────────────────────────
NSArray *identities = [PKGCertificatesUtilities availableIdentities];
for (NSString *name in identities) {
NSLog(@" %@", name);
}
// → Developer ID Installer: ACME Corp (XXXXXXXXXX)
```
--------------------------------
### Configure Regex Filter for PKGFileFilter
Source: https://context7.com/packagesdev/packages/llms.txt
Use this to create a regex-based file filter, for example, to exclude version control directories. Ensure the predicate is configured with `regularExpression = YES` and the desired pattern. Add the configured filter to the project's settings.
```objc
// ── Regex filter (exclude .git directories) ───────────────────────────────────
PKGFilePredicate *gitPred = [[PKGFilePredicate alloc] init];
gitPred.regularExpression = YES;
gitPred.pattern = @"^\\.git$";
gitPred.fileType = PKGFileSystemTypeFolder;
PKGFileFilter *gitFilter = [[PKGFileFilter alloc] init];
gitFilter.enabled = YES;
gitFilter.predicate = gitPred;
```
--------------------------------
### Get String from First Regex Match
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Returns a string created from the characters of the receiver that fall within the range of the first match of the given regular expression.
```objective-c
- (NSString *)stringByMatching:(NSString *)regexString;
```
--------------------------------
### Package Project Configuration (.pkgproj)
Source: https://context7.com/packagesdev/packages/llms.txt
Defines the structure of a .pkgproj file, which is an Apple Property List XML document used for configuring package projects. It includes settings for the project, individual packages, file installations, and scripts.
```xml
PROJECT
PROJECT_SETTINGS
NAME My Application Installer
BUILD_FORMAT 0
BUILD_PATH
PATH build
PATH_TYPE 1
REFERENCE_FOLDER_PATH
CERTIFICATE
PACKAGES
UUID A1B2C3D4-...
TYPE 0
PACKAGE_SETTINGS
NAME My Application
IDENTIFIER com.acme.myapp
VERSION 3.2.1
CONCLUSION_ACTION 0
LOCATION_TYPE 0
AUTHENTICATION 1
RELOCATABLE
HFS_COMPRESSION
PACKAGE_FILES
DEFAULT_INSTALL_LOCATION /
HIERARCHY
TYPE 0
PATH /
PATH_TYPE 0
UID 0
GID 0
PERMISSIONS 509
CHILDREN
TYPE 1
PATH Applications
PATH_TYPE 0
UID 0
GID 80
PERMISSIONS 509
CHILDREN
TYPE 3
PATH build/MyApp.app
PATH_TYPE 1
UID 0
GID 80
PERMISSIONS 493
SCRIPTS_AND_RESOURCES
PRE_INSTALLATION_SCRIPT
PATH scripts/preinstall.sh
PATH_TYPE 1
POST_INSTALLATION_SCRIPT
PATH scripts/postinstall.sh
PATH_TYPE 1
```
--------------------------------
### Demonstration of Match Enumerator
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
This example demonstrates using the match enumerator to find all lines in a string. It utilizes a regular expression with the multiline option enabled to match entire lines, including empty ones.
```objective-c
#import
#import "RegexKitLite.h"
#import "RKLMatchEnumerator.h"
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *searchString = @"one\ntwo\n\nfour\n";
NSEnumerator *matchEnumerator = NULL;
NSString *regexString = @"(?m)^.*$";
NSLog(@"searchString: '%@'", searchString);
NSLog(@"regexString : '%@'", regexString);
matchEnumerator = [searchString matchEnumeratorWithRegex:regexString];
NSUInteger line = 0;
NSString *matchedString = NULL;
while((matchedString = [matchEnumerator nextObject]) != NULL) {
NSLog(@"%d: %d '%@'", ++line, [matchedString length], matchedString);
}
[pool release];
return(0);
}
```
--------------------------------
### Basic RegexKit Lite Usage in Objective-C
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
An example of using RegexKit Lite to match a regular expression against a string and capture a specific group. This code snippet is intended to be compiled and run from the shell.
```objective-c
#import
#import
#import "RegexKitLite.h"
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Copyright COPYRIGHT_SIGN APPROXIMATELY_EQUAL_TO 2008
// Copyright \u00a9 \u2245 2008
char *utf8CString = "Copyright \xC2\xA9 \xE2\x89\x85 2008";
NSString *regexString = @"Copyright (.*) (\\d+)";
NSString *subjectString = [NSString stringWithUTF8String:utf8CString];
NSString *matchedString = [subjectString stringByMatching:regexString capture:1];
NSLog(@"subject: \"%@\"", subjectString);
NSLog(@"matched: \"%@\"", matchedString);
[pool release];
return(0);
}
```
--------------------------------
### Get Capture Count for Regex with Options and Error Handling
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Returns the number of captures a regular expression contains, with options for matching and error handling. Returns -1 if an error occurs.
```objective-c
+ (NSInteger)captureCountForRegex:(NSString *)regexString options:(RKLRegexOptions)options error:(NSError **)error;
```
--------------------------------
### Get String from Regex Match with Options, Range, and Capture
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Returns a string created from the characters of the receiver that fall within the range of a specific capture group for the first match of the given regular expression, using provided options and searching within a specified range.
```objective-c
- (NSString *)stringByMatching:(NSString *)regexString options:(RKLRegexOptions)options inRange:(NSRange)range capture:(NSInteger)capture error:(NSError **)error;
```
--------------------------------
### Programmatically Execute a Build Order
Source: https://context7.com/packagesdev/packages/llms.txt
Initiate a build process by submitting a PKGBuildOrder to the packages_dispatcher via XPC. Register for build events and handle completion or errors.
```objc
#import "PKGBuildOrderManager.h"
#import "PKGBuildOrder.h"
#import "PKGBuildNotificationCenter.h"
#import "PKGBuildStep+Constants.h"
// ── Assemble external settings ────────────────────────────────────────────────
NSDictionary *externalSettings = @{
PKGBuildOrderExternalSettingsBuildFolderKey : @"/Users/ci/build",
PKGBuildOrderExternalSettingsSigningIdentityKey: @"Developer ID Installer: ACME (XXXXXXXXXX)",
PKGBuildOrderExternalSettingsEmbedTimestamp : @YES,
PKGBuildOrderExternalSettingsUserDefinedSettingsKey: @{
@"PRODUCT_VERSION": @"3.2.1",
@"COPYRIGHT_YEAR" : @"2026"
}
};
// ── Create build order ────────────────────────────────────────────────────────
PKGBuildOrder *order = [[PKGBuildOrder alloc] init];
order.projectPath = @"/Projects/MyApp.pkgproj";
order.buildOptions = 0; // PKGBuildOptionDebugBuild | PKGBuildOptionLaunchAfterBuild
order.externalSettings = externalSettings;
// ── Execute ───────────────────────────────────────────────────────────────────
[[PKGBuildOrderManager defaultManager]
executeBuildOrder:order
setupHandler:^(PKGBuildNotificationCenter *center) {
// Register for step events
[[NSNotificationCenter defaultCenter]
addObserverForName:PKGBuildEventNotification
object:center
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *n) {
NSString *path = n.userInfo[PKGBuildStepPathKey];
NSNumber *state = n.userInfo[PKGBuildStateKey];
NSLog(@"[%%@] step: %%@",
state.unsignedIntegerValue == PKGBuildStepStateSuccess
? @"OK" : @" ",
path);
}];
}
completionHandler:^(PKGBuildResult result) {
switch (result) {
case PKGBuildResultSuccessful:
NSLog(@"Build succeeded");
break;
case PKGBuildResultAborted:
NSLog(@"Build aborted");
break;
case PKGBuildResultBuildOrderExecutionAgentDidExit:
NSLog(@"Builder agent exited unexpectedly");
break;
}
exit(result == PKGBuildResultSuccessful ? 0 : 1);
}
communicationErrorHandler:^(NSError *error) {
NSLog(@"XPC error: %%@", error);
exit(2);
}];
[[NSRunLoop mainRunLoop] run];
```
--------------------------------
### PKGProject - Loading and Saving Project Files
Source: https://context7.com/packagesdev/packages/llms.txt
Demonstrates how to load project files from disk or URL and save them back. It also shows how to determine the project type after loading.
```APIDOC
## Load a project from disk (type is determined automatically)
NSError *error = nil;
PKGProject *project = [PKGProject projectWithContentsOfFile:@"/Projects/MyApp.pkgproj" error:&error];
if (!project) {
NSLog(@"Load failed: %@", error.localizedDescription);
return;
}
// Determine project type
if (project.type == PKGProjectTypeDistribution) {
PKGDistributionProject *dist = (PKGDistributionProject *)project;
NSLog(@"Distribution project with %lu packages", dist.packageComponents.count);
} else {
PKGPackageProject *pkg = (PKGPackageProject *)project;
NSLog(@"Package: %@ version: %@",
pkg.packageSettings.name, pkg.packageSettings.version);
}
## Load from URL
NSURL *url = [NSURL fileURLWithPath:@"/Projects/Distribution.pkgproj"];
PKGDistributionProject *dist = (PKGDistributionProject *)
[PKGProject projectWithContentsOfURL:url error:&error];
## Save back to disk
dist.settings.name = @"My Application Installer";
BOOL ok = [dist writeToFile:@"/Projects/Distribution.pkgproj" atomically:YES];
NSLog(@"Save %@", ok ? @"succeeded" : @"failed");
```
--------------------------------
### Create and Resolve PKGFilePath References
Source: https://context7.com/packagesdev/packages/llms.txt
Demonstrates creating different types of PKGFilePath (absolute, relative to project, named) and resolving them to absolute paths using a PKGFilePathConverter. Also shows converting absolute paths back to typed file paths.
```objc
#import "PKGFilePath.h"
#import "PKGFilePathConverter.h"
// ── Create paths ─────────────────────────────────────────────────────────────
PKGFilePath *absolute = [PKGFilePath filePathWithAbsolutePath:@"/scripts/preinstall.sh"];
PKGFilePath *relative = [PKGFilePath filePathWithString:@"scripts/preinstall.sh"
type:PKGFilePathTypeRelativeToProject];
PKGFilePath *named = [PKGFilePath filePathWithName:@"preinstall.sh"];
NSLog(@"%d", (int)absolute.type); // 0 (PKGFilePathTypeAbsolute)
NSLog(@"%@", relative.lastPathComponent); // → preinstall.sh
// ── Resolve to absolute path using a converter ────────────────────────────────
PKGFilePathConverter *converter = [[PKGFilePathConverter alloc] init];
converter.referenceProjectPath = @"/Users/ci/Projects/MyApp.pkgproj";
converter.referenceFolderPath = @"/Volumes/BuildServer/sources";
NSString *abs = [converter absolutePathForFilePath:relative];
// → /Users/ci/Projects/scripts/preinstall.sh
// ── Convert an absolute path back to a typed file path ───────────────────────
PKGFilePath *fp = [converter filePathForAbsolutePath:@"/Volumes/BuildServer/sources/Assets/icon.png"
type:PKGFilePathTypeRelativeToReferenceFolder];
NSLog(@"%@", fp.string); // → Assets/icon.png
// ── Shift type in-place ───────────────────────────────────────────────────────
[converter shiftTypeOfFilePath:fp toType:PKGFilePathTypeAbsolute];
NSLog(@"%@", fp.string); // → /Volumes/BuildServer/sources/Assets/icon.png
```
--------------------------------
### Load and Save PKGProject Files
Source: https://context7.com/packagesdev/packages/llms.txt
Demonstrates loading a project from disk or URL and saving it back. The project type is determined automatically upon loading.
```objc
#import "PKGProject.h"
#import "PKGPackageProject.h"
#import "PKGDistributionProject.h"
// ── Load a project from disk (type is determined automatically) ──────────────
NSError *error = nil;
PKGProject *project = [PKGProject projectWithContentsOfFile:@"/Projects/MyApp.pkgproj"
error:&error];
if (!project) {
NSLog(@"Load failed: %@", error.localizedDescription);
return;
}
// Determine project type
if (project.type == PKGProjectTypeDistribution) {
PKGDistributionProject *dist = (PKGDistributionProject *)project;
NSLog(@"Distribution project with %lu packages", dist.packageComponents.count);
} else {
PKGPackageProject *pkg = (PKGPackageProject *)project;
NSLog(@"Package: %@ version: %@",
pkg.packageSettings.name, pkg.packageSettings.version);
}
// ── Load from URL ────────────────────────────────────────────────────────────
NSURL *url = [NSURL fileURLWithPath:@"/Projects/Distribution.pkgproj"];
PKGDistributionProject *dist = (PKGDistributionProject *)
[PKGProject projectWithContentsOfURL:url error:&error];
// ── Save back to disk ────────────────────────────────────────────────────────
dist.settings.name = @"My Application Installer";
BOOL ok = [dist writeToFile:@"/Projects/Distribution.pkgproj" atomically:YES];
NSLog(@"Save %@", ok ? @"succeeded" : @"failed");
```
--------------------------------
### Add and Check File Filters in Project Settings
Source: https://context7.com/packagesdev/packages/llms.txt
Demonstrates how to add configured file filters to project settings and perform a convenience check to see if a file should be filtered.
```objc
// ── Add filters to project settings ──────────────────────────────────────────
[project.settings.filesFilters addObject:filter];
[project.settings.filesFilters addObject:gitFilter];
// ── Convenience check via project settings ────────────────────────────────────
BOOL excluded = [project.settings shouldFilterFileNamed:@".DS_Store"
ofType:PKGFileSystemTypeFile];
NSLog(@"Excluded: %d", excluded); // → 1
```
--------------------------------
### Get Range of Regex Match
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Returns the range for the first match of the given regular expression in the receiver string.
```objective-c
- (NSRange)rangeOfRegex:(NSString *)regexString;
```
--------------------------------
### Manage Package Scripts and Resources
Source: https://context7.com/packagesdev/packages/llms.txt
Associate pre- and post-installation scripts with a package component. Scripts can be specified using absolute paths or paths relative to the project. The paths are managed using `PKGFilePath` objects.
```objc
#import "PKGPackageScriptsAndResources.h"
#import "PKGFilePath.h"
PKGPackageScriptsAndResources *scripts = [[PKGPackageScriptsAndResources alloc] init];
// Pre-install script (absolute path)
scripts.preInstallationScriptPath =
[PKGFilePath filePathWithAbsolutePath:@"/scripts/preinstall.sh"];
// Post-install script (relative to project)
scripts.postInstallationScriptPath =
[PKGFilePath filePathWithString:@"scripts/postinstall.sh"
type:PKGFilePathTypeRelativeToProject];
// Attach to a component
PKGPackageComponent *comp = [PKGPackageComponent projectComponent];
comp.scriptsAndResources = scripts;
// Inspect
NSLog(@"Pre: %@", comp.scriptsAndResources.preInstallationScriptPath.string);
NSLog(@"Post: %@", comp.scriptsAndResources.postInstallationScriptPath.string);
```
--------------------------------
### Compiling and Running RegexKit Lite from Shell
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Demonstrates how to compile and run a simple Objective-C program using RegexKit Lite from the command line. Ensure you link against the Foundation framework and the ICU library.
```shell
shell% cd examples
shell% gcc -g -I.. -o link_example link_example.m ../RegexKitLite.m -framework Foundation -licucore
```
```shell
shell% ./link_example
```
--------------------------------
### Manage Distribution Projects
Source: https://context7.com/packagesdev/packages/llms.txt
Load, modify, and save distribution projects. Use `PKGProject` to load an existing project, access its settings and package components, and add new components. Ensure to handle potential errors during loading.
```objc
#import "PKGDistributionProject.h"
#import "PKGPackageComponent.h"
#import "PKGDistributionProjectSettings.h"
// ── Load an existing distribution project ────────────────────────────────────
NSError *error = nil;
PKGDistributionProject *dist = (PKGDistributionProject *)
[PKGProject projectWithContentsOfFile:@"/Projects/Suite.pkgproj" error:&error];
PKGDistributionProjectSettings *settings =
(PKGDistributionProjectSettings *)dist.settings;
settings.buildFormat = PKGProjectBuildFormatFlat;
settings.name = @"ACME Suite Installer";
// ── Iterate package components ───────────────────────────────────────────────
for (PKGPackageComponent *comp in dist.packageComponents) {
NSLog(@"UUID: %@ type: %lu name: %@",
comp.UUID,
(unsigned long)comp.type,
comp.packageSettings.name);
}
// ── Look up a component ──────────────────────────────────────────────────────
PKGPackageComponent *comp =
[dist packageComponentWithIdentifier:@"com.acme.framework"];
NSLog(@"Found: %@", comp.packageSettings.name);
// ── Add a new project component ──────────────────────────────────────────────
PKGPackageComponent *newComp = [PKGPackageComponent projectComponent];
newComp.packageSettings.name = @"ACME Helper";
newComp.packageSettings.identifier = @"com.acme.helper";
newComp.packageSettings.version = @"1.0.0";
[dist.packageComponents addObject:newComp];
// ── Check whether it is flat ─────────────────────────────────────────────────
NSLog(@"Flat: %d", dist.isFlat); // → 1
// ── Save ─────────────────────────────────────────────────────────────────────
[dist writeToFile:@"/Projects/Suite.pkgproj" atomically:YES];
```
--------------------------------
### Configure Simple Glob Filter for PKGFileFilter
Source: https://context7.com/packagesdev/packages/llms.txt
Use this to create a simple glob-based file filter. Ensure the predicate is configured with `regularExpression = NO` and the desired pattern. Add the configured filter to the project's settings.
```objc
#import "PKGFileFilter.h"
// ── Simple glob filter (disable .DS_Store) ────────────────────────────────────
PKGFilePredicate *pred = [[PKGFilePredicate alloc] init];
pred.regularExpression = NO;
pred.pattern = @".DS_Store";
pred.fileType = PKGFileSystemTypeFile;
PKGFileFilter *filter = [[PKGFileFilter alloc] init];
filter.enabled = YES;
filter.predicate = pred;
NSLog(@"%d", [filter matchesFileNamed:@".DS_Store" ofType:PKGFileSystemTypeFile]); // → 1
NSLog(@"%d", [filter matchesFileNamed:@"Info.plist" ofType:PKGFileSystemTypeFile]); // → 0
```
--------------------------------
### Get Range of Regex Match within Range
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Returns the range for the first match of the given regular expression within a specified range of the receiver string.
```objective-c
- (NSRange)rangeOfRegex:(NSString *)regexString inRange:(NSRange)range;
```
--------------------------------
### Get Range of Specific Capture in Regex Match
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Returns the range of a specific capture group for the first match of the given regular expression in the receiver string.
```objective-c
- (NSRange)rangeOfRegex:(NSString *)regexString capture:(NSInteger)capture;
```
--------------------------------
### Execute Full Distribution Build
Source: https://context7.com/packagesdev/packages/llms.txt
Run the `build.sh` script from the distribution directory to perform a full build including application, package, and DMG. This script manages the dependency order for sub-projects.
```sh
cd /path/to/packages-repo/distribution
./build.sh
# Builds: goldin → packagesutil → packagesbuild → packages_dispatcher →
# packages_builder → all requirement plugins → all locator plugins →
# Packages.app GUI → Packages.pkg → Packages.dmg
```
--------------------------------
### Create PKGFileItem from File System Path
Source: https://context7.com/packagesdev/packages/llms.txt
Use PKGFileItem to represent a file system item sourced from disk. Provide the file path, owner (uid), group (gid), and permissions.
```objc
// ── File system item sourced from disk ───────────────────────────────────────
PKGFilePath *srcPath = [PKGFilePath filePathWithAbsolutePath:@"/build/MyApp.app"];
PKGFileItem *appItem = [PKGFileItem fileSystemItemWithFilePath:srcPath
uid:0
gid:80
permissions:0755];
```
--------------------------------
### Configure PKGPackageSettings Metadata
Source: https://context7.com/packagesdev/packages/llms.txt
Initializes and configures PKGPackageSettings for a single package, including basic metadata, post-install behavior, authorization, and payload options. Also shows serialization and deserialization.
```objc
#import "PKGPackageSettings.h"
PKGPackageSettings *settings = [[PKGPackageSettings alloc] init];
// Basic metadata
settings.name = @"MyApplication";
settings.identifier = @"com.acme.myapp";
settings.version = @"3.2.1";
// Post-install behavior
settings.conclusionAction = PKGPackageConclusionActionRequireRestart;
// Authorization
settings.authenticationMode = PKGPackageAuthenticationRoot;
// Payload options
settings.relocatable = NO;
settings.overwriteDirectoryPermissions = YES;
settings.followSymbolicLinks = NO;
settings.useHFSPlusCompression = YES;
// Package location (embedded in distribution)
settings.locationType = PKGPackageLocationEmbedded;
// Package location (external HTTP URL)
settings.locationType = PKGPackageLocationHTTPSURL;
settings.locationURL = @"https://cdn.acme.com/packages/myapp-3.2.1.pkg";
// Derived helpers
NSString *scheme = [settings locationScheme]; // → @"https"
NSString *path = [settings locationPath]; // → @"//cdn.acme.com/packages/myapp-3.2.1.pkg"
// Serialize to / from representation
NSMutableDictionary *rep = [settings representation];
PKGPackageSettings *restored = [[PKGPackageSettings alloc]
initWithRepresentation:rep error:nil];
NSLog(@"%@ %@", restored.identifier, restored.version);
// → com.acme.myapp 3.2.1
```
--------------------------------
### Get Capture Count for Regex
Source: https://github.com/packagesdev/packages/blob/master/RegexKitLite-1.2/RegexKitLite.html
Returns the number of captures a regular expression contains. Returns -1 if an error occurs, otherwise returns the number of captures (0 if none).
```objective-c
+ (NSInteger)captureCountForRegex:(NSString *)regexString;
```
--------------------------------
### Create DMG Image
Source: https://context7.com/packagesdev/packages/llms.txt
Use `hdiutil` commands to convert a template DMG, attach it, copy the package, detach, and then convert to a compressed format. This process is handled by `build.sh`.
```sh
hdiutil convert template.dmg -format UDRW -o build/diskimage_rw.dmg
hdiutil attach build/diskimage_rw.dmg -mountpoint /Volumes/PackagesDMG
cp build/Packages.pkg /Volumes/PackagesDMG/
hdiutil detach /Volumes/PackagesDMG
hdiutil convert build/diskimage_rw.dmg -format UDZO -o "build/Packages 1.2.11.dmg"
```