Irbisa · Шпаргалка
Сборка Xcode и модуляризация
Таргеты, схемы, xcconfig, SPM, статическая и динамическая линковка, XCFramework, время сборки
Чем отличаются target, scheme и build configuration, и чем
.xcodeprojотличается от.xcworkspace?Как выбрать минимальную версию iOS (deployment target) и как пользоваться новыми API, не поднимая её?
import SwiftUI struct RootView: View { var body: some View { if #available(iOS 18, *) { // runtime check: only this branch may use the iOS 18 Tab API…Что такое сертификат подписи, provisioning profile и entitlements, и как они связаны между собой?
Чем отличаются CocoaPods, Carthage и Swift Package Manager, и почему большинство команд перешли на SPM?
Что делает эта функция в Debug-сборке и в Release-сборке, и почему поведение различается?
func loadItem(id: Int?) -> String { assert(id != nil, "id is required") #if DEBUG print("loading \(String(describing: id))") #endif precondition((id ?? 0) >= 0, "negative id") return "item-\(id ?? -1)"} print(loadItem(id: nil))Зачем нужны
.xcconfig-файлы и в каком порядке Xcode вычисляет build setting?// Config/Base.xcconfig: shared by every configurationSWIFT_VERSION = 6.0IPHONEOS_DEPLOYMENT_TARGET = 17.0CODE_SIGN_STYLE = Automatic // Config/Staging.xcconfig: assigned to the Staging configuration…Что происходит, когда вы нажимаете Build в Xcode: от графа задач до подписанного приложения?
Чем в
Package.swiftотличаются target, product и package dependency, и почему другой пакет не может импортировать ваш таргет?// swift-tools-version: 6.0import PackageDescription let package = Package( name: "Networking", platforms: [.iOS(.v17)],…Как Swift Package Manager выбирает версии зависимостей и почему
Package.resolvedнужно коммитить?// swift-tools-version: 6.0import PackageDescription let package = Package( name: "AppModules", dependencies: […Что такое XCFramework и почему он заменил fat-фреймворки, собранные через
lipo?set -euo pipefail # One archive per platform variant: device and simulator are both arm64,# so lipo cannot merge them into one binary.xcodebuild archive -scheme Analytics \ -destination "generic/platform=iOS" -archivePath build/ios \…SwiftLint и кодогенератор запускаются на каждой сборке, даже когда ничего не менялось: чего не хватает системе сборки и как это исправить?
# Run Script phase, wrong: no inputs or outputs, so it runs on every build,# and rewriting Strings.swift recompiles everything that uses it.# swiftlint --fix# Tools/gen-strings Resources/Localizable.xcstrings > Sources/Generated/Strings.swift # Run Script phase, right.…Что такое app thinning и почему размер универсального
.ipa, размер загрузки для устройства и размер после установки различаются?set -euo pipefail xcodebuild archive -workspace App.xcworkspace -scheme App \ -configuration Release -destination 'generic/platform=iOS' \ -archivePath build/App.xcarchive…Что такое privacy manifest (
PrivacyInfo.xcprivacy) и что будет со сборкой без него?<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>NSPrivacyTracking</key> <false/>…Как сборка попадает из Xcode в App Store и что по пути происходит в TestFlight и на App Review?
Как настроить CI/CD для iOS-приложения и как решить подпись кода на CI-машине?
# fastlane/Fastfiledefault_platform(:ios) platform :ios do lane :beta do setup_ci # temporary keychain on CI runners, no-op locally…Чем статическая линковка отличается от динамической на iOS и почему холодный запуск замедлился, когда двенадцать модулей стали динамическими фреймворками?
В этом манифесте динамические фреймворки
FeedиProfileоба зависят отAnalytics: что пойдёт не так в рантайме и как это исправить?let package = Package( name: "App", products: [ .library(name: "Analytics", type: .static, targets: ["Analytics"]), .library(name: "Feed", type: .dynamic, targets: ["Feed"]), .library(name: "Profile", type: .dynamic, targets: ["Profile"]), ], targets: [ .target(name: "Analytics"), // holds AnalyticsTracker.shared .target(name: "Feed", dependencies: ["Analytics"]), .target(name: "Profile", dependencies: ["Analytics"]), ])Изменение одной строки в фича-модуле стоит двенадцати минут сборки: как выяснить, что на самом деле пересобирается, и исправить это?
set -euo pipefailSIM='generic/platform=iOS Simulator' # 1. Where does the time go? Per-task durations (open the Build Timeline in Xcode too)xcodebuild -workspace App.xcworkspace -scheme App -destination "$SIM" \ build -showBuildTimingSummary…Все типы фича-пакета стали
publicтолько ради того, чтобы приложение собралось: чего это стоит и что модуль должен выставлять наружу?import SwiftUI // Package.swift: one product, two targets that share internalslet package = Package( name: "Checkout", products: [.library(name: "Checkout", targets: ["Checkout"])],…Checkout должен открывать редактор адреса из Profile, а Profile должен открывать платёжный экран из Checkout, и SwiftPM отвергает цикл: как его разорвать?
import Foundation // Package.swift: interface targets break the cyclelet package = Package( name: "Features", products: […Что такое ABI stability и module stability и к чему обязывает SDK включённый
BUILD_LIBRARY_FOR_DISTRIBUTION?// Framework built with BUILD_LIBRARY_FOR_DISTRIBUTION = YES // Not frozen: you may add a case in 2.0public enum PaymentState: Sendable { case pending case settled(id: String)…Зачем большие команды генерируют Xcode-проект через Tuist или XcodeGen и как мигрировать проект на 200 таргетов, не замораживая работу над фичами?
import ProjectDescription // Project.swift: the target graph as reviewable source, no pbxproj in gitlet project = Project( name: "App", settings: .settings(configurations: […