I am engaged on an iOS undertaking that consists of two targets: a most important undertaking and a Widget extension. In an effort to share the content material mannequin between these targets and allow modification of information and states inside the primary app, I made a decision to put the mannequin in a separate bundle positioned inside the primary undertaking.
This is my setup:
Foremost undertaking
- Comprises the primary app goal
- Comprises the content material mannequin bundle
Widget extension - Makes use of the content material mannequin from the bundle
Nevertheless, I am encountering a problem. Whereas each targets can discover the shared mannequin, when trying to create a stay exercise, the @most important operate of the widget extension will not be being known as.
I am in search of steerage on the most effective practices for modularization and dependency administration on this situation. Particularly, what would possibly I be doing incorrect in my present strategy? How can I be certain that each the primary app and the widget extension can correctly entry and make the most of the shared content material mannequin with out operating into points just like the @most important operate not being known as?
Any insights or solutions on strategy this downside can be tremendously appreciated. Thanks!
That is the undertaking.yml I exploit (xcodegen) to offer you a greater perception in my setup:
title: MyApp
choices:
xcodeVersion: 15.2.0
configs:
Debug-Dev: debug
Debug-Prod: debug
Launch-Dev: launch
Launch-Prod: launch
settings:
base:
DEVELOPMENT_TEAM: 0000000000
SWIFT_VERSION: "5.5"
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED: YES
configs:
Debug-Dev:
SWIFT_COMPILATION_MODE: "incremental"
Debug-Prod:
SWIFT_COMPILATION_MODE: "incremental"
Launch-Dev:
SWIFT_COMPILATION_MODE: "wholemodule"
Launch-Prod:
SWIFT_COMPILATION_MODE: "wholemodule"
attributes:
ORGANIZATIONNAME: MyOranization
packages:
AppSpecifics:
path: Modules/AppSpecifics
group: Modules
Options:
path: Modules/Options
group: Modules
targets:
MyApp:
sort: software
platform: iOS
deploymentTarget: "17.0"
configFiles:
Debug-Dev: Challenge/Configurations/Dev.xcconfig
Debug-Prod: Challenge/Configurations/Prod.xcconfig
Launch-Dev: Challenge/Configurations/Dev.xcconfig
Launch-Prod: Challenge/Configurations/Prod.xcconfig
settings:
base:
PRODUCT_NAME: MyApp
MARKETING_VERSION: 1.0.0
CURRENT_PROJECT_VERSION: 1
TARGETED_DEVICE_FAMILY: "1"
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon$(APP_NAME_SUFFIX)
information:
path: Challenge/Data.plist
properties:
CFBundleDisplayName: MyApp$(APP_NAME_SUFFIX)
CFBundleVersion: $(CURRENT_PROJECT_VERSION)
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
UILaunchStoryboardName: LaunchScreen.storyboard
UIRequiredDeviceCapabilities: [armv7]
ITSAppUsesNonExemptEncryption: NO
LSRequiresIPhoneOS: YES
_Configuration: $(CONFIGURATION)
_ServerEnvironment: $(SERVER_ENVIRONMENT)
NSLocationWhenInUseUsageDescription: "{See InfoPlist.strings for Localization}"
NSLocationAlwaysAndWhenInUseUsageDescription: "{See InfoPlist.strings for Localization}"
UIStatusBarStyle: UIStatusBarStyleLightContent
UIViewControllerBasedStatusBarAppearance: "NO"
NSSupportsLiveActivities: "YES"
UIBackgroundModes:
- location
sources:
- Challenge
dependencies:
- bundle: AppSpecifics
- bundle: Options
- bundle: Dependencies
postCompileScripts:
- script: |
$SRCROOT/build_phases/scripts/swiftlint.sh;
title: SwiftLint
- script: |
$SRCROOT/build_phases/scripts/licenses.sh;
title: License Plist
- script: |
$SRCROOT/build_phases/scripts/crashlytics.sh;
title: Crashlytics
MyAppWidget:
platform: iOS
deploymentTarget: "17.0"
sort: app-extension
settings:
base:
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: ${inherited}
PRODUCT_NAME: MyAppWidget
PRODUCT_MODULE_NAME: MyAppWidget
DEVELOPMENT_TEAM: 0000000000
configFiles:
Debug-Dev: Challenge/Configurations/Widget-Dev.xcconfig
Debug-Prod: Challenge/Configurations/Widget-Prod.xcconfig
Launch-Dev: Challenge/Configurations/Widget-Dev.xcconfig
Launch-Prod: Challenge/Configurations/Widget-Prod.xcconfig
information:
path: Widget/MyAppWidget.plist
properties:
NSExtension:
NSExtensionPointIdentifier: 'com.apple.widgetkit-extension'
sources:
- path: Widget
dependencies:
- bundle: AppSpecifics
schemes:
MyApp-DEV:
construct:
targets:
MyApp: all
MyAppWidget: all
run:
config: Debug-Dev
check:
config: Debug-Dev
testPlans:
- path: Challenge/Testplans/MyApp-CI-UnitTests.xctestplan
defaultPlan: true
- path: Challenge/Testplans/MyApp-Weekly.xctestplan
profile:
config: Launch-Dev
analyze:
config: Launch-Dev
archive:
config: Launch-Dev
MyApp-PROD:
construct:
targets:
MyApp: all
MyAppWidget: all
run:
config: Debug-Prod
check:
config: Debug-Prod
testPlans:
- path: Challenge/Testplans/MyApp-CI-UnitTests.xctestplan
defaultPlan: true
- path: Challenge/Testplans/MyApp-Weekly.xctestplan
profile:
config: Launch-Prod
analyze:
config: Launch-Prod
archive:
config: Launch-Prod
I attempted creating an personal goal “Shared” however appeared overkill and by some means didn’t work. (possibly there is a appropriate means on do it) I anticipated that this additional module provides me the power to run the Liveactivity