Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2026-02-03 08:51:24 -06:00
parent 052e4715dc
commit ab8ef49ddb
6 changed files with 95 additions and 22 deletions

View File

@ -32,8 +32,8 @@
/* Begin PBXFileReference section */
EA836ABF2F0ACE8A00077F87 /* SelfieCam.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SelfieCam.app; sourceTree = BUILT_PRODUCTS_DIR; };
EA836ACC2F0ACE8B00077F87 /* SelfieCamTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SelfieCamTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
EA836AD62F0ACE8B00077F87 /* SelfieCamUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SelfieCamUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
EA836ACC2F0ACE8B00077F87 /* SelfieCam.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SelfieCam.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
EA836AD62F0ACE8B00077F87 /* SelfieCam.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SelfieCam.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
EACONFIG002 /* SelfieCam/Configuration/Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SelfieCam/Configuration/Debug.xcconfig; sourceTree = SOURCE_ROOT; };
EACONFIG003 /* SelfieCam/Configuration/Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SelfieCam/Configuration/Release.xcconfig; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
@ -100,8 +100,8 @@
isa = PBXGroup;
children = (
EA836ABF2F0ACE8A00077F87 /* SelfieCam.app */,
EA836ACC2F0ACE8B00077F87 /* SelfieCamTests.xctest */,
EA836AD62F0ACE8B00077F87 /* SelfieCamUITests.xctest */,
EA836ACC2F0ACE8B00077F87 /* SelfieCam.xctest */,
EA836AD62F0ACE8B00077F87 /* SelfieCam.xctest */,
);
name = Products;
sourceTree = "<group>";
@ -164,7 +164,7 @@
packageProductDependencies = (
);
productName = SelfieCamTests;
productReference = EA836ACC2F0ACE8B00077F87 /* SelfieCamTests.xctest */;
productReference = EA836ACC2F0ACE8B00077F87 /* SelfieCam.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
EA836AD52F0ACE8B00077F87 /* SelfieCamUITests */ = {
@ -187,7 +187,7 @@
packageProductDependencies = (
);
productName = SelfieCamUITests;
productReference = EA836AD62F0ACE8B00077F87 /* SelfieCamUITests.xctest */;
productReference = EA836AD62F0ACE8B00077F87 /* SelfieCam.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
@ -436,6 +436,11 @@
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "$(PRODUCT_NAME)";
INFOPLIST_KEY_PublicAppName = "$(PRODUCT_NAME)";
INFOPLIST_KEY_AppGroupIdentifier = "$(APP_GROUP_IDENTIFIER)";
INFOPLIST_KEY_CloudKitContainerIdentifier = "$(CLOUDKIT_CONTAINER_IDENTIFIER)";
INFOPLIST_KEY_AppClipDomain = "$(APPCLIP_DOMAIN)";
INFOPLIST_KEY_NSCameraUsageDescription = "SelfieCam needs camera access to display your live selfie preview, apply real-time filters and ring light effects, capture high-quality photos, and enable advanced features like Center Stage auto-framing.";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "SelfieCam needs microphone access for the camera framework to initialize properly. Audio is not recorded.";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "SelfieCam needs photo library access to automatically save your captured photos to your device, making them available in the Photos app and other compatible applications.";
@ -451,7 +456,7 @@
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = "$(PRODUCT_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
@ -473,6 +478,11 @@
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "$(PRODUCT_NAME)";
INFOPLIST_KEY_PublicAppName = "$(PRODUCT_NAME)";
INFOPLIST_KEY_AppGroupIdentifier = "$(APP_GROUP_IDENTIFIER)";
INFOPLIST_KEY_CloudKitContainerIdentifier = "$(CLOUDKIT_CONTAINER_IDENTIFIER)";
INFOPLIST_KEY_AppClipDomain = "$(APPCLIP_DOMAIN)";
INFOPLIST_KEY_NSCameraUsageDescription = "SelfieCam needs camera access to display your live selfie preview, apply real-time filters and ring light effects, capture high-quality photos, and enable advanced features like Center Stage auto-framing.";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "SelfieCam needs microphone access for the camera framework to initialize properly. Audio is not recorded.";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "SelfieCam needs photo library access to automatically save your captured photos to your device, making them available in the Photos app and other compatible applications.";
@ -488,7 +498,7 @@
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = "$(PRODUCT_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
@ -510,7 +520,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(TESTS_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = "$(PRODUCT_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = NO;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
@ -532,7 +542,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(TESTS_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = "$(PRODUCT_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = NO;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
@ -552,7 +562,7 @@
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(UITESTS_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = "$(PRODUCT_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = NO;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
@ -572,7 +582,7 @@
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(UITESTS_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)";
PRODUCT_NAME = "$(PRODUCT_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = NO;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;

View File

@ -36,7 +36,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EA836ACB2F0ACE8B00077F87"
BuildableName = "SelfieCamTests.xctest"
BuildableName = "Selfie Cam.xctest"
BlueprintName = "SelfieCamTests"
ReferencedContainer = "container:SelfieCam.xcodeproj">
</BuildableReference>
@ -47,7 +47,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EA836AD52F0ACE8B00077F87"
BuildableName = "SelfieCamUITests.xctest"
BuildableName = "Selfie Cam.xctest"
BlueprintName = "SelfieCamUITests"
ReferencedContainer = "container:SelfieCam.xcodeproj">
</BuildableReference>

View File

@ -0,0 +1,45 @@
import Foundation
enum AppIdentifiers {
// Read from Info.plist (values come from xcconfig)
static let publicAppName: String = {
Bundle.main.object(forInfoDictionaryKey: "PublicAppName") as? String
?? "SelfieCam"
}()
static let appGroupIdentifier: String = {
Bundle.main.object(forInfoDictionaryKey: "AppGroupIdentifier") as? String
?? "group.com.mbrucedogs.SelfieCam"
}()
static let cloudKitContainerIdentifier: String = {
Bundle.main.object(forInfoDictionaryKey: "CloudKitContainerIdentifier") as? String
?? "iCloud.com.mbrucedogs.SelfieCam"
}()
static let appClipDomain: String = {
Bundle.main.object(forInfoDictionaryKey: "AppClipDomain") as? String
?? "yourapp.example.com"
}()
// Derived from bundle identifier
static var bundleIdentifier: String {
Bundle.main.bundleIdentifier ?? "com.mbrucedogs.SelfieCam"
}
static var watchBundleIdentifier: String {
"\(bundleIdentifier).watchkitapp"
}
static var appClipBundleIdentifier: String {
"\(bundleIdentifier).Clip"
}
static var widgetBundleIdentifier: String {
"\(bundleIdentifier).Widget"
}
static func appClipURL(recordName: String) -> URL? {
URL(string: "https://\(appClipDomain)/appclip?id=\(recordName)")
}
}

View File

@ -6,13 +6,23 @@
// =============================================================================
COMPANY_IDENTIFIER = com.mbrucedogs
APP_NAME = SelfieCam
BUNDLE_ID_NAME = SelfieCam
PRODUCT_NAME = Selfie Cam
DEVELOPMENT_TEAM = 6R7KLBPBLZ
// =============================================================================
// DERIVED IDENTIFIERS - DO NOT EDIT
// =============================================================================
APP_BUNDLE_IDENTIFIER = $(COMPANY_IDENTIFIER).$(APP_NAME)
TESTS_BUNDLE_IDENTIFIER = $(COMPANY_IDENTIFIER).$(APP_NAME)Tests
UITESTS_BUNDLE_IDENTIFIER = $(COMPANY_IDENTIFIER).$(APP_NAME)UITests
APP_BUNDLE_IDENTIFIER = $(COMPANY_IDENTIFIER).$(BUNDLE_ID_NAME)
WATCH_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).watchkitapp
APPCLIP_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).Clip
WIDGET_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).Widget
INTENT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).Intent
TESTS_BUNDLE_IDENTIFIER = $(COMPANY_IDENTIFIER).$(BUNDLE_ID_NAME)Tests
UITESTS_BUNDLE_IDENTIFIER = $(COMPANY_IDENTIFIER).$(BUNDLE_ID_NAME)UITests
APP_GROUP_IDENTIFIER = group.$(COMPANY_IDENTIFIER).$(BUNDLE_ID_NAME)
CLOUDKIT_CONTAINER_IDENTIFIER = iCloud.$(COMPANY_IDENTIFIER).$(BUNDLE_ID_NAME)
APPCLIP_DOMAIN = yourapp.example.com

View File

@ -2,7 +2,15 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>$(CLOUDKIT_CONTAINER_IDENTIFIER)</string>
</array>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
<string>$(TeamIdentifierPrefix)$(APP_BUNDLE_IDENTIFIER)</string>
<key>com.apple.security.application-groups</key>
<array>
<string>$(APP_GROUP_IDENTIFIER)</string>
</array>
</dict>
</plist>