几天后,我已经厌倦了混乱的构建设置...
我有一个应用程序,我们称它为MyiPhoneApp
,它使用大约10个 private /自定义框架(Cocoa Touch Dynamic Framework)。 MyiPhoneApp
也将Cocoapods用于某些依赖项(不相关?)。我的 private 框架自己在使用自己(彼此依赖)。
因此,我的设置是(此处为便于阅读而简化):
框架( private /自定义可可触摸动态):Models
目标: ViewModels
,ViewModelsTests
取决于 private 框架:无ViewModels
定位:ViewModels
,ViewModelsTests
取决于 private 框架:Models
Views
定位:Views
,Views
依赖于 private 框架:Models
,ViewModels
应用MyiPhoneApp
:
定位:MyiPhoneApp
,MyiPhoneAppTests
,MyiPhoneAppUITests
取决于 private 框架的 MyiPhoneApp
:Models
,ViewModels
和Views
捕获22个正在运行的单元测试并上传到iTunesConnect
使用ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
和的所有目标,我可以在每个专用框架中运行所有单元测试。 但是然后我从iTunes Connect收到拒绝错误:
[04:06:20]:[运输器错误输出]:错误ITMS-90206:“无效
束。位于“MyiPhoneApp.app/Frameworks/Models.framework”的捆绑软件
包含不允许的文件'Frameworks'。” [04:06:20]:[传输器错误
输出]:错误ITMS-90206:“无效的捆绑包。捆绑包位于
“MyiPhoneApp.app/Frameworks/ViewModels.framework”包含不允许
文件“Frameworks”。” [04:06:20]:[传输器错误输出]:错误
ITMS-90206:“无效的捆绑包。捆绑包位于
'MyiPhoneApp.app/Frameworks/Views.framework'包含不允许的文件
'构架'。”
这似乎类似于:
(SO Q958)[Validation Error: Invalid Bundle. The bundle at ... contains disallowed file 'Frameworks'
Q958的The answer with over 240 upvotes,建议:
为Frameworks和Tests目标(和Frameworks的Test Target ..?)设置ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
,为Apps设置YES
。 this Github comment也建议这样做
尝试尝试时(框架及其测试目标的ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
),我无法运行测试。
当我尝试运行ModelTests
(记住Framwork Models
不依赖于任何其他框架)时,测试失败/死于:
dyld:未加载库:@ rpath / libswiftCore.dylib引用自:
/Users/sajjon/Library/Developer/Xcode/DerivedData/Models-ahgxztzgogwcfheblqbzabdqxhtm/Build/Products/Debug-iphonesimulator/Models.framework/Models
原因:找不到图片
什么是正确的设置?
我已经尝试过Xcode 9.3和Xcode 9.4。我的框架和我的应用程序使用以下xcconfig文件:
我的系统
Macbook Pro 15英寸2016年末
macOS High Sierra v 10.13.5(17F77)
椰子足1.5.3(捆绑包)
Bundler版本1.16.1bundle exec pod --version => 1.5.3
我的Podfilesource 'https://github.com/CocoaPods/Specs.git'
platform :ios, '11.2'
inhibit_all_warnings!
use_frameworks!
workspace 'MyWorkspace.xcworkspace'
### PODS (sorted by name) ###
def nimble
pod 'Nimble', '~> 7.1'
end
def rxswift
pod 'RxSwift', '~> 4.1'
end
def viewcomposer
pod 'ViewComposer', :git => 'https://github.com/Sajjon/ViewComposer.git'
end
def quick
pod 'Quick', '~> 1.3'
end
# Rest of pods removed for this StackOverFlow question for readability #
# Global Pod used by ___ALL___ targets
swiftlint
#@@ Apps (sorted by name) @@#
target 'MyiPhoneApp' do
project 'Apps/MyiPhoneApp/MyiPhoneApp'
# lots of pods removed for this SO question for readability
rxswift
tinyconstraints
viewcomposer
abstract_target 'Tests' do
nimble
quick
target "MyiPhoneAppTests"
target "MyiPhoneAppUITests"
end
end
### PRIVATE FRAMEWORKS ###
abstract_target 'Framework-Models' do
project 'Common/Models/Models'
target 'Models' do
# lots of pods removed for this SO question for readability
rxswift
swiftybeaver
end
target 'ModelsTests' do
nimble
quick
end
end
abstract_target 'Framework-ViewModels' do
project 'Common/ViewModels/ViewModels'
target 'ViewModels' do
# lots of pods removed for this SO question for readability
rxswift
viewcomposer
end
target 'ViewModelsTests' do
nimble
quick
end
end
abstract_target 'Framework-Views' do
project 'Common/Views/Views'
target 'Views' do
# lots of pods removed for this SO question for readability
rxswift
tinyconstraints
viewcomposer
end
target 'ViewsTests' do
nimble
quick
end
end
我的xcconfig文件设置
因此,如您在上面的Podfile中看到的那样,我的 private Framework使用Pod。但是我想使用xcconfig文件在我的框架之间共享构建设置(我只写了三个ViewModels
,Views
和Models
,但实际上我大约有10个。)
因此,我研究了Xcode默认为Apps,Cocoa Touch Dynamic Frameworks创建的xcconfig文件,以及在测试目标和非测试目标之间以及在调试和发布之间,这些设置的区别。
由此,我创建了这些xcconfig文件base_shared.xcconfig
包括配置: NONE
说明:由所有目标(应用程序(主要,测试,UITest),框架(主要,测试))使用。base_debug.xcconfig
包括配置: NONE
说明:由所有调试目标(应用程序(主要,测试,UITest),框架(主要,测试))使用。base_release.xcconfig
包括配置: NONE
说明:由所有发行目标(应用程序(主要,测试,UITest),框架(主要,测试))使用。base_apps.xcconfig
包括配置: base_shared
说明:由应用程序目标(主要,测试,UITest)使用base_framework.xcconfig
包括配置: base_shared
说明:由框架(主要,测试)使用。base_tests.xcconfig
包括配置: base_shared
说明:由所有测试目标(应用程序,框架)使用。base_uitests.xcconfig
包括配置: base_shared
说明:由所有UITest目标(应用程序)使用。
然后,对于每个应用程序框架,我在Common
xcconfig中包括xcconfig的正确组合。所以对于框架Models
,我创建6个配置文件:Models-Common.xcconfig
,Models-Debug.xcconfig
,Models-Release.xcconfig
,“ModelsTests-Common.xcconfig”,ModelsTests-Debug.xcconfig
,ModelsTests-Release.xcconfig
。
虽然这会产生许多xcconfig文件,每个框架6个,但它们都很小。而且,我可以在所有10多个框架之间共享所有构建设置。这是一个权衡。
我的xcconfig文件的内容base_shared.xcconfig
:// BuildSettings shared between both DEBUG and RELEASE and also identical for both FRAMEWORKS (Cocoa Touch Framework) and APPS (iOS)
// Vanilla Xcode 9.3 settings
ALWAYS_SEARCH_USER_PATHS = NO
CLANG_ANALYZER_NONNULL = YES
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE
CLANG_CXX_LANGUAGE_STANDARD = gnu++14
CLANG_CXX_LIBRARY = libc++
CLANG_ENABLE_MODULES = YES
CLANG_ENABLE_OBJC_ARC = YES
CLANG_ENABLE_OBJC_WEAK = YES
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES
CLANG_WARN_BOOL_CONVERSION = YES
CLANG_WARN_COMMA = YES
CLANG_WARN_CONSTANT_CONVERSION = YES
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR
CLANG_WARN_DOCUMENTATION_COMMENTS = YES
CLANG_WARN_EMPTY_BODY = YES
CLANG_WARN_ENUM_CONVERSION = YES
CLANG_WARN_INFINITE_RECURSION = YES
CLANG_WARN_INT_CONVERSION = YES
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES
CLANG_WARN_STRICT_PROTOTYPES = YES
CLANG_WARN_SUSPICIOUS_MOVE = YES
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
CLANG_WARN_UNREACHABLE_CODE = YES
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
COPY_PHASE_STRIP = NO
ENABLE_STRICT_OBJC_MSGSEND = YES
GCC_C_LANGUAGE_STANDARD = gnu11
GCC_NO_COMMON_BLOCKS = YES
SDKROOT = iphoneos
GCC_WARN_64_TO_32_BIT_CONVERSION = YES
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR
GCC_WARN_UNDECLARED_SELECTOR = YES
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE
GCC_WARN_UNUSED_FUNCTION = YES
GCC_WARN_UNUSED_VARIABLE = YES
IPHONEOS_DEPLOYMENT_TARGET = 11.2
// Custom set
CODE_SIGN_STYLE = Manual
SWIFT_VERSION = 4.1
DEVELOPMENT_TEAM = MYTEAMIDGOESHERE
ENABLE_BITCODE = NO
CODE_SIGN_ENTITLEMENTS =
CODE_SIGN_IDENTITY =
base_debug.xcconfig
:_DEBUG = DEBUG
GCC_PREPROCESSOR_DEFINITIONS = $(_DEBUG)
DEBUG_INFORMATION_FORMAT = dwarf
ENABLE_TESTABILITY = YES
GCC_DYNAMIC_NO_PIC = NO
GCC_OPTIMIZATION_LEVEL = 0
MTL_ENABLE_DEBUG_INFO = YES
ONLY_ACTIVE_ARCH = YES
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG
SWIFT_OPTIMIZATION_LEVEL = -Onone
SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(_DEBUG)
base_release.xcconfig
:DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
ENABLE_NS_ASSERTIONS = NO
MTL_ENABLE_DEBUG_INFO = NO
SWIFT_COMPILATION_MODE = wholemodule
SWIFT_OPTIMIZATION_LEVEL = -O
VALIDATE_PRODUCT = YES
base_apps.xcconfig
:#include "base_shared.xcconfig"
// Apps have no specific BuildSettings that the FRAMEWORKS does not have as well. But in the future they might have, thus we have this file.
// These settings were in the TravelCompanion xcconfig
SWIFT_ACTIVE_COMPILATION_CONDITIONS[sdk=iphonesimulator*] = $(inherited) IOS_SIMULATOR
MTL_ENABLE_DEBUG_INFO = NO
SWIFT_OPTIMIZATION_LEVEL = -O
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
ENABLE_NS_ASSERTIONS = NO
VALIDATE_PRODUCT = YES
SUPPORTED_PLATFORMS = iphonesimulator iphoneos
VALID_ARCHS = arm64 armv7 armv7s
CLANG_MODULES_AUTOLINK = YES
GCC_OPTIMIZATION_LEVEL = s
CLANG_ENABLE_CODE_COVERAGE = NO
TARGETED_DEVICE_FAMILY = 1
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES
VERSIONING_SYSTEM = apple_generic
// Custom
// The flag `ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES` should be set to `YES` for apps and `NO` for frameworks
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
base_framework.xcconfig
:#include "base_shared.xcconfig"
// BuildSettings specific for FRAMEWORKS (Cocoa Touch Framework)
// Vanilla BuildSettings
CURRENT_PROJECT_VERSION = 1
VERSIONING_SYSTEM = apple-generic
VERSION_INFO_PREFIX =
// Custom Set
PRODUCT_NAME = $(TARGET_NAME:c99extidentifier)
INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/Frameworks
DYLIB_COMPATIBILITY_VERSION = 1
DYLIB_CURRENT_VERSION = 1
DEFINES_MODULE = YES
SKIP_INSTALL = YES
// The flag `ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES` should be set to `YES` for apps and `NO` for frameworks
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @loader_path/Frameworks
base_tests.xcconfig
:#include "base_shared.xcconfig"
ONLY_ACTIVE_ARCH = YES
//Only used by APPS but it does not mess up build settings for test targets for FRAMEWORKS in Xcode 9.3 so will keep it here for now
BUNDLE_LOADER = $(TEST_HOST)
base_uitests.xcconfig
:#include "base_shared.xcconfig"
TEST_TARGET_NAME = $(PRODUCT_NAME)
Models-Common.xcconfig
:#include "../../../../Configurations/base_framework.xcconfig"
INFOPLIST_FILE = Source/SupportingFiles/Models-Info.plist
PRODUCT_BUNDLE_IDENTIFIER = com.sajjon.Models
Models-Debug.xcconfig
:#include "Models-Common.xcconfig"
#include "../../../../Configurations/base_debug.xcconfig"
#include "../../Pods/Target Support Files/Pods-Framework-Models-Models/Pods-Framework-Models-Models.debug.xcconfig"
Models-Release.xcconfig
:#include "Models-Common.xcconfig"
#include "../../../../Configurations/base_release.xcconfig"
#include "../../Pods/Target Support Files/Pods-Framework-Models-Models/Pods-Framework-Models-Models.release.xcconfig"
ModelsTests-Common.xcconfig
:#include "../../../../Configurations/base_framework.xcconfig"
#include "../../../../Configurations/base_tests.xcconfig"
INFOPLIST_FILE = Tests/SupportingFiles/ModelsTests-Info.plist
ModelsTests-Debug.xcconfig
:#include "ModelsTests-Common.xcconfig"
#include "../../../../Configurations/base_debug.xcconfig"
#include "../../Pods/Target Support Files/Pods-Framework-Models-ModelsTests/Pods-Framework-Models-ModelsTests.debug.xcconfig"
ModelsTests-Release.xcconfig
:#include "ModelsTests-Common.xcconfig"
#include "../../../../Configurations/base_release.xcconfig"
#include "../../Pods/Target Support Files/Pods-Framework-Models-ModelsTests/Pods-Framework-Models-ModelsTests.release.xcconfig"
MyiPhoneApp-Commong.xcconfig
:#include "../../../../Configurations/base_apps.xcconfig"
_APP_NAME_PROD = My iPhone App
_BUNDLE_IDENTIFIER_PROD = com.sajjon.myiphoneaop
INFOPLIST_FILE = Source/SupportingFiles/MyiPhoneApp-Info.plist
DEVELOPMENT_TEAM = MYTEAMGOESHERE
PRODUCT_NAME = $(_APP_NAME_PROD)
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage
CODE_SIGN_ENTITLEMENTS = Source/SupportingFiles/$(_APP_NAME_PROD).entitlements
SWIFT_OBJC_BRIDGING_HEADER = Source/SupportingFiles/MyiPhoneApp-Bridging-Header.h
PRODUCT_MODULE_NAME = TravelCompanion
// Overridden in Debug.xcconfig
CODE_SIGN_IDENTITY = iPhone Distribution
// Overridden in Release.xcconfig
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-Alpha
ENABLE_TESTABILITY = YES
MyiPhoneApp-Debug.xcconfig
:#include "MyiPhoneApp-Common.xcconfig"
#include "../../../../Configurations/base_debug.xcconfig"
#include "../../Pods/Target Support Files/Pods-MyiPhoneApp/Pods-MyiPhoneApp.debug.xcconfig"
_DEBUG = DEBUG
_CODE_SIGN_ID_DEBUG = iPhone Developer
_BUNDLE_IDENTIFIER_DEBUG = $(_BUNDLE_IDENTIFIER_PROD).dev
_PP_DEBUG = match Development $(_BUNDLE_IDENTIFIER_DEBUG)
CODE_SIGN_IDENTITY = $(_CODE_SIGN_ID_DEBUG)
PROVISIONING_PROFILE_SPECIFIER = $(_PP_DEBUG)
PRODUCT_BUNDLE_IDENTIFIER = $(_BUNDLE_IDENTIFIER_DEBUG)
APP_DISPLAY_NAME = MyiPhoneApp
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-Debug
SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(_DEBUG)
GCC_PREPROCESSOR_DEFINITIONS = $(_DEBUG)
GCC_OPTIMIZATION_LEVEL = 0
GCC_OPTIMIZATION_LEVEL = 0
MTL_ENABLE_DEBUG_INFO = YES
SWIFT_OPTIMIZATION_LEVEL = -Onone
GCC_DYNAMIC_NO_PIC = NO
ONLY_ACTIVE_ARCH = YES
ENABLE_NS_ASSERTIONS = YES
ENABLE_NS_ASSERTIONS[sdk=iphoneos*] = YES
VALIDATE_PRODUCT = NO
MyiPhoneApp-Release.xcconfig
:#include "MyiPhoneApp-Common.xcconfig"
#include "../../../../Configurations/base_release.xcconfig"
#include "../../Pods/Target Support Files/Pods-MyiPhoneApp/Pods-MyiPhoneApp.release.xcconfig"
_PP_PROD = match AppStore $(_BUNDLE_IDENTIFIER_PROD)
PROVISIONING_PROFILE_SPECIFIER = $(_PP_PROD)
PRODUCT_BUNDLE_IDENTIFIER = $(_BUNDLE_IDENTIFIER_PROD)
APP_DISPLAY_NAME = $(_APP_NAME_PROD)
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-Production
SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) APP_STORE_BUILD
SWIFT_OPTIMIZATION_LEVEL = -Owholemodule
最佳答案
在我们的项目中,我们有很多自定义框架,我们也遇到了类似的问题。对于每个框架,我们有两个构建配置,分别是DEBUG和RELEASE。而且,我们仅启用了ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES,用于我们用来运行测试的DEBUG构建。
关于ios - Xcode 9.3 Swift嵌套自定义框架单元测试和iTunesConnect上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50746080/