Add Quick Look Preview and Thumbnail extensions for .casera files

- Add CaseraQLPreview extension to show custom preview with contractor
  details and import instructions when viewing .casera files
- Add CaseraQLThumbnail extension to display teal icon in Messages
  and Files app instead of generic white box
- Update UTExportedTypeDeclarations to conform to public.content
  for better system file type recognition

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-06 02:11:20 -06:00
parent e13f2702a5
commit 997932f0df
8 changed files with 778 additions and 2 deletions

View File

@@ -10,6 +10,10 @@
1C0789402EBC218B00392B46 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C07893F2EBC218B00392B46 /* WidgetKit.framework */; };
1C0789422EBC218B00392B46 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C0789412EBC218B00392B46 /* SwiftUI.framework */; };
1C0789532EBC218D00392B46 /* CaseraExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 1C07893D2EBC218B00392B46 /* CaseraExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
1C81F26B2EE416EE000739EA /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C81F26A2EE416EE000739EA /* QuickLook.framework */; };
1C81F2772EE416EF000739EA /* CaseraQLPreview.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 1C81F2692EE416EE000739EA /* CaseraQLPreview.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
1C81F2822EE41BB6000739EA /* QuickLookThumbnailing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C81F2812EE41BB6000739EA /* QuickLookThumbnailing.framework */; };
1C81F2892EE41BB6000739EA /* CaseraQLThumbnail.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 1C81F2802EE41BB6000739EA /* CaseraQLThumbnail.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -20,6 +24,20 @@
remoteGlobalIDString = 1C07893C2EBC218B00392B46;
remoteInfo = CaseraExtension;
};
1C81F2752EE416EF000739EA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6A3E1D84F9F1A2FD92A75A6C /* Project object */;
proxyType = 1;
remoteGlobalIDString = 1C81F2682EE416EE000739EA;
remoteInfo = CaseraQLPreview;
};
1C81F2872EE41BB6000739EA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6A3E1D84F9F1A2FD92A75A6C /* Project object */;
proxyType = 1;
remoteGlobalIDString = 1C81F27F2EE41BB6000739EA;
remoteInfo = CaseraQLThumbnail;
};
1CBF16002ECD8AE4001BF56C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6A3E1D84F9F1A2FD92A75A6C /* Project object */;
@@ -44,6 +62,8 @@
dstSubfolderSpec = 13;
files = (
1C0789532EBC218D00392B46 /* CaseraExtension.appex in Embed Foundation Extensions */,
1C81F2892EE41BB6000739EA /* CaseraQLThumbnail.appex in Embed Foundation Extensions */,
1C81F2772EE416EF000739EA /* CaseraQLPreview.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
@@ -56,6 +76,10 @@
1C0789412EBC218B00392B46 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
1C0789612EBC2F5400392B46 /* CaseraExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CaseraExtension.entitlements; sourceTree = "<group>"; };
1C685CD22EC5539000A9669B /* CaseraTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CaseraTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
1C81F2692EE416EE000739EA /* CaseraQLPreview.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = CaseraQLPreview.appex; sourceTree = BUILT_PRODUCTS_DIR; };
1C81F26A2EE416EE000739EA /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; };
1C81F2802EE41BB6000739EA /* CaseraQLThumbnail.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = CaseraQLThumbnail.appex; sourceTree = BUILT_PRODUCTS_DIR; };
1C81F2812EE41BB6000739EA /* QuickLookThumbnailing.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLookThumbnailing.framework; path = System/Library/Frameworks/QuickLookThumbnailing.framework; sourceTree = SDKROOT; };
1C87A0C42EDB8ED40081E450 /* CaseraUITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = CaseraUITests.xctestplan; sourceTree = "<group>"; };
1CBF1BED2ECD9768001BF56C /* CaseraUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CaseraUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4B07E04F794A4C1CAA8CCD5D /* PhotoViewerSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoViewerSheet.swift; sourceTree = "<group>"; };
@@ -85,6 +109,20 @@
);
target = 1CBF1BEC2ECD9768001BF56C /* CaseraUITests */;
};
1C81F27B2EE416EF000739EA /* Exceptions for "CaseraQLPreview" folder in "CaseraQLPreview" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 1C81F2682EE416EE000739EA /* CaseraQLPreview */;
};
1C81F28D2EE41BB6000739EA /* Exceptions for "CaseraQLThumbnail" folder in "CaseraQLThumbnail" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 1C81F27F2EE41BB6000739EA /* CaseraQLThumbnail */;
};
1C87A67A2EDCC3100081E450 /* Exceptions for "iosApp" folder in "CaseraExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
@@ -125,6 +163,22 @@
path = CaseraTests;
sourceTree = "<group>";
};
1C81F26C2EE416EE000739EA /* CaseraQLPreview */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
1C81F27B2EE416EF000739EA /* Exceptions for "CaseraQLPreview" folder in "CaseraQLPreview" target */,
);
path = CaseraQLPreview;
sourceTree = "<group>";
};
1C81F2832EE41BB6000739EA /* CaseraQLThumbnail */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
1C81F28D2EE41BB6000739EA /* Exceptions for "CaseraQLThumbnail" folder in "CaseraQLThumbnail" target */,
);
path = CaseraQLThumbnail;
sourceTree = "<group>";
};
1CBF1BEE2ECD9768001BF56C /* CaseraUITests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
@@ -167,6 +221,22 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
1C81F2662EE416EE000739EA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1C81F26B2EE416EE000739EA /* QuickLook.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1C81F27D2EE41BB6000739EA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1C81F2822EE41BB6000739EA /* QuickLookThumbnailing.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1CBF1BEA2ECD9768001BF56C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -189,6 +259,8 @@
children = (
1C07893F2EBC218B00392B46 /* WidgetKit.framework */,
1C0789412EBC218B00392B46 /* SwiftUI.framework */,
1C81F26A2EE416EE000739EA /* QuickLook.framework */,
1C81F2812EE41BB6000739EA /* QuickLookThumbnailing.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -212,6 +284,8 @@
1C0789432EBC218B00392B46 /* Casera */,
1C685CD32EC5539000A9669B /* CaseraTests */,
1CBF1BEE2ECD9768001BF56C /* CaseraUITests */,
1C81F26C2EE416EE000739EA /* CaseraQLPreview */,
1C81F2832EE41BB6000739EA /* CaseraQLThumbnail */,
1C07893E2EBC218B00392B46 /* Frameworks */,
FA6022B7B844191C54E57EB4 /* Products */,
1C078A1B2EC1820B00392B46 /* Recovered References */,
@@ -225,6 +299,8 @@
1C07893D2EBC218B00392B46 /* CaseraExtension.appex */,
1C685CD22EC5539000A9669B /* CaseraTests.xctest */,
1CBF1BED2ECD9768001BF56C /* CaseraUITests.xctest */,
1C81F2692EE416EE000739EA /* CaseraQLPreview.appex */,
1C81F2802EE41BB6000739EA /* CaseraQLThumbnail.appex */,
);
name = Products;
sourceTree = "<group>";
@@ -277,6 +353,50 @@
productReference = 1C685CD22EC5539000A9669B /* CaseraTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
1C81F2682EE416EE000739EA /* CaseraQLPreview */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1C81F2782EE416EF000739EA /* Build configuration list for PBXNativeTarget "CaseraQLPreview" */;
buildPhases = (
1C81F2652EE416EE000739EA /* Sources */,
1C81F2662EE416EE000739EA /* Frameworks */,
1C81F2672EE416EE000739EA /* Resources */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
1C81F26C2EE416EE000739EA /* CaseraQLPreview */,
);
name = CaseraQLPreview;
packageProductDependencies = (
);
productName = CaseraQLPreview;
productReference = 1C81F2692EE416EE000739EA /* CaseraQLPreview.appex */;
productType = "com.apple.product-type.app-extension";
};
1C81F27F2EE41BB6000739EA /* CaseraQLThumbnail */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1C81F28A2EE41BB6000739EA /* Build configuration list for PBXNativeTarget "CaseraQLThumbnail" */;
buildPhases = (
1C81F27C2EE41BB6000739EA /* Sources */,
1C81F27D2EE41BB6000739EA /* Frameworks */,
1C81F27E2EE41BB6000739EA /* Resources */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
1C81F2832EE41BB6000739EA /* CaseraQLThumbnail */,
);
name = CaseraQLThumbnail;
packageProductDependencies = (
);
productName = CaseraQLThumbnail;
productReference = 1C81F2802EE41BB6000739EA /* CaseraQLThumbnail.appex */;
productType = "com.apple.product-type.app-extension";
};
1CBF1BEC2ECD9768001BF56C /* CaseraUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1CBF1BF52ECD9768001BF56C /* Build configuration list for PBXNativeTarget "CaseraUITests" */;
@@ -314,6 +434,8 @@
);
dependencies = (
1C0789522EBC218D00392B46 /* PBXTargetDependency */,
1C81F2762EE416EF000739EA /* PBXTargetDependency */,
1C81F2882EE41BB6000739EA /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
E822E6B231E7783DE992578C /* iosApp */,
@@ -342,6 +464,12 @@
CreatedOnToolsVersion = 26.1.1;
TestTargetID = D4ADB376A7A4CFB73469E173;
};
1C81F2682EE416EE000739EA = {
CreatedOnToolsVersion = 26.1.1;
};
1C81F27F2EE41BB6000739EA = {
CreatedOnToolsVersion = 26.1.1;
};
1CBF1BEC2ECD9768001BF56C = {
CreatedOnToolsVersion = 26.1.1;
TestTargetID = D4ADB376A7A4CFB73469E173;
@@ -369,6 +497,8 @@
1C07893C2EBC218B00392B46 /* CaseraExtension */,
1C685CD12EC5539000A9669B /* CaseraTests */,
1CBF1BEC2ECD9768001BF56C /* CaseraUITests */,
1C81F2682EE416EE000739EA /* CaseraQLPreview */,
1C81F27F2EE41BB6000739EA /* CaseraQLThumbnail */,
);
};
/* End PBXProject section */
@@ -388,6 +518,20 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
1C81F2672EE416EE000739EA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
1C81F27E2EE41BB6000739EA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
1CBF1BEB2ECD9768001BF56C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -441,6 +585,20 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
1C81F2652EE416EE000739EA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
1C81F27C2EE41BB6000739EA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
1CBF1BE92ECD9768001BF56C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -463,6 +621,16 @@
target = 1C07893C2EBC218B00392B46 /* CaseraExtension */;
targetProxy = 1C0789512EBC218D00392B46 /* PBXContainerItemProxy */;
};
1C81F2762EE416EF000739EA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 1C81F2682EE416EE000739EA /* CaseraQLPreview */;
targetProxy = 1C81F2752EE416EF000739EA /* PBXContainerItemProxy */;
};
1C81F2882EE41BB6000739EA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 1C81F27F2EE41BB6000739EA /* CaseraQLThumbnail */;
targetProxy = 1C81F2872EE41BB6000739EA /* PBXContainerItemProxy */;
};
1CBF16012ECD8AE4001BF56C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D4ADB376A7A4CFB73469E173 /* Casera */;
@@ -622,6 +790,130 @@
};
name = Release;
};
1C81F2792EE416EF000739EA /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = V3PF3M6B6U;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = CaseraQLPreview/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = CaseraQLPreview;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 26.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tt.casera.CaseraDev.CaseraQLPreview;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
1C81F27A2EE416EF000739EA /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = V3PF3M6B6U;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = CaseraQLPreview/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = CaseraQLPreview;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 26.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tt.casera.CaseraDev.CaseraQLPreview;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
1C81F28B2EE41BB6000739EA /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = V3PF3M6B6U;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = CaseraQLThumbnail/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = CaseraQLThumbnail;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 26.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tt.casera.CaseraDev.CaseraQLThumbnail;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
1C81F28C2EE41BB6000739EA /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = V3PF3M6B6U;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = CaseraQLThumbnail/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = CaseraQLThumbnail;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 26.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tt.casera.CaseraDev.CaseraQLThumbnail;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
1CBF1BF62ECD9768001BF56C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -852,6 +1144,24 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1C81F2782EE416EF000739EA /* Build configuration list for PBXNativeTarget "CaseraQLPreview" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1C81F2792EE416EF000739EA /* Debug */,
1C81F27A2EE416EF000739EA /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1C81F28A2EE41BB6000739EA /* Build configuration list for PBXNativeTarget "CaseraQLThumbnail" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1C81F28B2EE41BB6000739EA /* Debug */,
1C81F28C2EE41BB6000739EA /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1CBF1BF52ECD9768001BF56C /* Build configuration list for PBXNativeTarget "CaseraUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (