¡Hola!
¿Alguna vez te has preguntado qué hay dentro de una App Playground en Swift Playgrounds? Bueno, tengo algo genial para ti. En este video, te muestro cómo configurar todo desde cero: desde el archivo Package.swift
hasta agregar tus propios módulos, e incluso cómo hacer pruebas unitarias (que, por ahora, solo funcionan en Xcode, ¡pero crucemos los dedos para Swift Playgrounds también! 🤞).
En este repositorio, expuse todo lo que necesitas saber sobre Package.swift
y muchas otras cosas. También hay un proyecto de muestra y algunos enlaces que podrían resultar realmente útiles.
¡Espero que te ayude y te diviertas tanto como yo!
// swift-tools-version: 5.9
// WARNING:
// This file is automatically generated.
// Do not edit it by hand because the contents will be replaced.
import PackageDescription
import AppleProductTypes
let package = Package(
name: "YouTube",
defaultLocalization: "en",
platforms: [
.iOS("17.0")
],
products: [
.library(
name: "ExampleKit",
targets: ["ExampleKit"]
),
.iOSApplication(
name: "YouTube",
targets: ["AppModule"],
bundleIdentifier: "com.alemohamad.YouTube",
teamIdentifier: "YOUR-TEAM-IDENTIFIER",
displayVersion: "1.0",
bundleVersion: "1",
appIcon: .asset("AppIcon"),
accentColor: .asset("AccentColor"),
supportedDeviceFamilies: [
.pad,
.phone
],
supportedInterfaceOrientations: [
.portrait,
.landscapeRight,
.landscapeLeft,
.portraitUpsideDown(.when(deviceFamilies: [.pad]))
],
appCategory: .education,
additionalInfoPlistContentFilePath: "AppInfo.plist"
)
],
targets: [
.executableTarget(
name: "AppModule",
dependencies: [
"ExampleKit"
]
),
.target(
name: "ExampleKit"
),
.testTarget(
name: "AppModuleTest",
dependencies: [
"ExampleKit"
]
)
]
)
Note Importante: Después de completar el proyecto, descubrí un problema crítico: si AppModule
incluye la carpeta Assets.xcassets
, hace que testTarget
falle, rompiendo todo el proyecto en Xcode. Para resolver esto y garantizar que el proyecto funcione correctamente, tuve que modificar la dependencia de testTarget
de AppModule
a ExampleKit
. Y funciona porque ExampleKit
contiene la lógica que pretendo probar. Todo lo demás queda como se demuestra en el vídeo.
platforms: [
.iOS("17.0"),
.macOS("14.0"),
.watchOS("10.0"),
.tvOS("17.0"),
.visionOS("1.0"),
.macCatalyst("17.0"),
.driverKit("23.0"),
.linux(""),
.openbsd(""),
.wasi(""), // WebAssembly System Interafce
.android(""),
.windows(""),
.custom("")
],
.iOS("17.0")
.iOS(.v17)
.iOS("16.1")
.iOS(.v16_1) // la constante no funciona en versiones menores, debes usar solo la principal
// Swift Playgrounds soporta estas versiones de iOS:
// 17.0
// 16.0, 16.1, 16.2, 16.3, 16.4, 16.5, 16.6
// 15.2, 15.3, 15.4, 15.5, 15.6
products: [
.library(name: "", type: .dynamic, targets: []), // .static
.executable(name: "", targets: []),
.plugin(name: "", targets: []),
.iOSApplication(name: "", targets: []) // sólo en el framework AppleProductTypes
],
supportedDeviceFamilies: [
.phone,
.pad,
.tv, // ?
.carPlay, // ?
.mac, // ?
.vision, // ?
.unspecified // ?
]
supportedInterfaceOrientations: [
.portrait,
.portraitUpsideDown,
.landscapeRight,
.landscapeLeft,
.faceUp,
.faceDown,
.unknown
]
appIcon: .placeholder(icon: .coffee),
appIcon: .asset("AppIcon"),
// 54 iconos:
// .bird .bunny .cat .dog .butterfly
// .flower .leaf .carrot .bowl .coffee
// .sandwich .twoPeople .running .calendar .camera
// .clock .gamepad .map .movieReel .palette
// .pencil .openBook .calculator .images .mic
// .box .coins .weights .paper .tv
// .binoculars .bandage .magicWand .gift .rocket
// .earth .beachball .barChart .heart .note
// .smiley .star .location .lightningBolt .checkmark
// .chatMessage .sparkle .bicycle .boat .car
// .plane .moon .sun .cloud
accentColor: .presetColor(.orange),
accentColor: .asset("AccentColor"),
// 12 colores:
// .red .orange .yellow
// .green .mint .teal
// .cyan .blue .indigo
// .purple .pink .brown
.books // Books
.business // Business
.developerTools // Developer Tools
.education // Education
.entertainment // Entertainment
.finance // Finance
.food-and-drink // Food & Drink
.games // Games
.actionGames // Games - Action Games
.adventureGames // Games - Adventure Games
.boardGames // Games - Board Games
.cardGames // Games - Card Games
.casinoGames // Games - Casino Games
.arcadeGames // Games - Casual Games
.familyGames // Games - Family Games
.kidsGames // Games - Kids Games
.musicGames // Games - Music Games
.puzzleGames // Games - Puzzle Games
.racingGames // Games - Racing Games
.rolePlayingGames // Games - Role Playing Games
.simulationGames // Games - Simulation Games
.sportsGames // Games - Sports Games
.strategyGames // Games - Strategy Games
.triviaGames // Games - Trivia Games
.wordGames // Games - Word Games
.graphicsDesign // Graphics & Design
.healthcareFitness // Health & Fitness
.lifestyle // Lifestyle
.magazines-and-newspapers // Magazines & Newspapers
.medical // Medical
.music // Music
.navigation // Navigation
.news // News
.photography // Photography
.productivity // Productivity
.reference // Reference
.shopping // Shopping
.socialNetworking // Social Networking
.sports // Sports
.travel // Travel
.utilities // Utilities
.video // Video
.weather // Weather
.target(name: "")
.executableTarget(name: "")
.testTarget(name: "")
.systemLibrary(name: "")
.binaryTarget(name: "", path: "")
.plugin(name: "")
- "Swift Playgrounds App Projects" by Aaron Sky (Nov 6, 2021)
- "A document-based app in Swift Playgrounds for iPad" by Guilherme Rambo (Dec 28, 2021)
- "Lessons from Developing an App on the iPad in Swift Playgrounds from Start to Finish (Including Publishing on the App Store)" by Matt Waller (Jan 4, 2022)
- "Changing the Thumbnail of an App in Swift Playgrounds" by Tiago Gomes Pereira (Apr 7, 2022)