diff --git a/samples/build.gradle.kts b/samples/build.gradle.kts index 7fd1a66c6b4..5dd47dbed61 100644 --- a/samples/build.gradle.kts +++ b/samples/build.gradle.kts @@ -58,6 +58,7 @@ val buildSamplesWithPlatformLibs by tasks.creating { dependsOn(":opengl:assemble") dependsOn(":uikit:assemble") dependsOn(":coverage:assemble") + dependsOn(":watchos:assemble") } if (isWindows) { diff --git a/samples/settings.gradle.kts b/samples/settings.gradle.kts index f932a91617e..0ca74cea3fb 100644 --- a/samples/settings.gradle.kts +++ b/samples/settings.gradle.kts @@ -44,8 +44,9 @@ if (isMacos) { include(":opengl") include(":uikit") include(":coverage") + include(":watchos") } if (isWindows) { include(":win32") -} \ No newline at end of file +} diff --git a/samples/uikit/README.md b/samples/uikit/README.md index 647055855e7..2d15faadf19 100644 --- a/samples/uikit/README.md +++ b/samples/uikit/README.md @@ -5,22 +5,16 @@ Apple devices, such as an iPhone. To build and run the sample do the following: -1. Open `samples/uikit/konan.xcodeproj` with Xcode. +1. Open `UIKitSample.xcodeproj` with Xcode, set development team to your own + and make bundle ID unique in project settings. + or +1a. Similarly modify `bundleIdPrefix` and `DEVELOPMENT_TEAM` in `project.yml` and + then generate Xcode project with `xcodegen` (https://github.com/yonaskolb/XcodeGen/). -2. Open the project's target through project navigator, go to tab 'General'. - In 'Identity' section change the bundle ID to the unique string in - reverse-DNS format. Then select the team in 'Signing' section. +2. Now build and run the application with Xcode on a connected iPhone or simulator. - See the - [Xcode documentation](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/ConfiguringYourApp/ConfiguringYourApp.html#//apple_ref/doc/uid/TP40012582-CH28-SW2) - for more info. +Note that in this example we do not use storyboards, and instead create user interface +components programmatically. Defining UI with storyboards in pure Kotlin iOS applications +is supported as well. -3. Now build and run the application on a connected iPhone with Xcode. - (The compilation will be slow for the first time). -The sample consists of the Xcode project and Kotlin source code. Xcode project -contains the UI built with Interface Builder and headers for Objective-C classes, -which are implemented in Kotlin. - -During build the executable compiled from Objective-C sources is replaced with -the one compiled from Kotlin sources. diff --git a/samples/uikit/UIKitSample.xcodeproj/project.pbxproj b/samples/uikit/UIKitSample.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..395ea46b015 --- /dev/null +++ b/samples/uikit/UIKitSample.xcodeproj/project.pbxproj @@ -0,0 +1,342 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 301A7F7B2E38A0507DE50BE1 /* ViewController.kt in Resources */ = {isa = PBXBuildFile; fileRef = 4CD08237C99EE51EF77078BB /* ViewController.kt */; }; + 562ACC5BA848F15EF1C8CA10 /* main.kt in Resources */ = {isa = PBXBuildFile; fileRef = FC430E849C9519096FC79E83 /* main.kt */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 4CD08237C99EE51EF77078BB /* ViewController.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ViewController.kt; sourceTree = ""; }; + 6B07A266844DA0A0E37CC68F /* UIKitSample.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = UIKitSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FC430E849C9519096FC79E83 /* main.kt */ = {isa = PBXFileReference; lastKnownFileType = text; path = main.kt; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 363F3F70F599800876E80E01 = { + isa = PBXGroup; + children = ( + BBFEA7F68D9D6C62F2908D66 /* src */, + 69EF9C159A26B77EFF55F942 /* Products */, + ); + sourceTree = ""; + }; + 63755DA7308C68AF59C587B3 /* kotlin */ = { + isa = PBXGroup; + children = ( + FC430E849C9519096FC79E83 /* main.kt */, + 4CD08237C99EE51EF77078BB /* ViewController.kt */, + ); + path = kotlin; + sourceTree = ""; + }; + 69EF9C159A26B77EFF55F942 /* Products */ = { + isa = PBXGroup; + children = ( + 6B07A266844DA0A0E37CC68F /* UIKitSample.app */, + ); + name = Products; + sourceTree = ""; + }; + B54757CDD36230AE01923800 /* iosMain */ = { + isa = PBXGroup; + children = ( + 63755DA7308C68AF59C587B3 /* kotlin */, + ); + path = iosMain; + sourceTree = ""; + }; + BBFEA7F68D9D6C62F2908D66 /* src */ = { + isa = PBXGroup; + children = ( + B54757CDD36230AE01923800 /* iosMain */, + ); + path = src; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F5227B97658961C9C73A6F2E /* UIKitSample */ = { + isa = PBXNativeTarget; + buildConfigurationList = B1A8070BD396A498BD833DC3 /* Build configuration list for PBXNativeTarget "UIKitSample" */; + buildPhases = ( + 9147B4CF5C06D4CF77ACF3FC /* GradleCompile */, + BE9081AF451571B84021AC67 /* Sources */, + D848DE0D231736CAB55BD443 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = UIKitSample; + productName = UIKitSample; + productReference = 6B07A266844DA0A0E37CC68F /* UIKitSample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2F795AF76B32ABD2043FD7B6 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + TargetAttributes = { + F5227B97658961C9C73A6F2E = { + DevelopmentTeam = N462MKSJ7M; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 0D29F0838E0A64A05D02D666 /* Build configuration list for PBXProject "UIKitSample" */; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 363F3F70F599800876E80E01; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F5227B97658961C9C73A6F2E /* UIKitSample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D848DE0D231736CAB55BD443 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 301A7F7B2E38A0507DE50BE1 /* ViewController.kt in Resources */, + 562ACC5BA848F15EF1C8CA10 /* main.kt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 9147B4CF5C06D4CF77ACF3FC /* GradleCompile */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = GradleCompile; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "$SRCROOT/../gradlew -p $SRCROOT/.. packForXcode\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + BE9081AF451571B84021AC67 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 30240F2C5B94778954FDDD23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + ENABLE_BITCODE = YES; + INFOPLIST_FILE = plists/Ios/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.UIKitSample; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = arm64; + }; + name = Release; + }; + ACEFD109F7738D0AE3383B13 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + 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_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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 4; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = N462MKSJ7M; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + 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; + MARKETING_VERSION = 1.0; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_VERSION = 5.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C3420161DB9AF86DB7EEDFBE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + ENABLE_BITCODE = YES; + INFOPLIST_FILE = plists/Ios/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.UIKitSample; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = arm64; + }; + name = Debug; + }; + CDD41CD31E42F4CB22754575 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + 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_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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 4; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = N462MKSJ7M; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + ); + 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; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0D29F0838E0A64A05D02D666 /* Build configuration list for PBXProject "UIKitSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CDD41CD31E42F4CB22754575 /* Debug */, + ACEFD109F7738D0AE3383B13 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + B1A8070BD396A498BD833DC3 /* Build configuration list for PBXNativeTarget "UIKitSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C3420161DB9AF86DB7EEDFBE /* Debug */, + 30240F2C5B94778954FDDD23 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ""; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2F795AF76B32ABD2043FD7B6 /* Project object */; +} diff --git a/samples/uikit/konan.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/samples/uikit/UIKitSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 72% rename from samples/uikit/konan.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to samples/uikit/UIKitSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 2a5e9d7e587..919434a6254 100644 --- a/samples/uikit/konan.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/samples/uikit/UIKitSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/samples/uikit/konan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/samples/uikit/UIKitSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from samples/uikit/konan.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to samples/uikit/UIKitSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/samples/uikit/build.gradle b/samples/uikit/build.gradle deleted file mode 100644 index 3a40e8a42b7..00000000000 --- a/samples/uikit/build.gradle +++ /dev/null @@ -1,60 +0,0 @@ -plugins { - id 'kotlin-multiplatform' -} - -kotlin { - targets { - fromPreset(determinePreset(), 'ios') { - binaries { - executable { - entryPoint = 'sample.uikit.main' - } - } - } - } -} - -// Special Gradle task that is called from Xcode. -// Two Gradle properties must be specified for this task: -// - uikit.configuration.name=[Release|Debug] -// - uikit.binary.location -task buildAppForXcode { - if (isCalledFromXcode()) { - dependsOn kotlin.targets.ios.binaries.getExecutable(getBuildTypeForXcode()).linkTask - } - - doLast { - if (!isCalledFromXcode()) { - throw new Exception("Please run 'buildAppForXcode' task with all necessary properties!") - } - - copy { - from file(kotlin.targets.ios.binaries.getExecutable(getBuildTypeForXcode()).outputFile) - into file(getBinaryLocationForXcode().parentFile) - rename { - getBinaryLocationForXcode().name - } - } - } -} - -// If custom preset specified in 'uikit.preset.name' property, then use it for building. -// Otherwise build for iPhone simulator (by default). -private def determinePreset() { - String presetName = project.hasProperty('uikit.preset.name') ? project.properties['uikit.preset.name'] : 'iosX64' - def preset = project.kotlin.presets[presetName] - println("$project has been configured for $presetName platform.") - preset -} - -private boolean isCalledFromXcode() { - project.hasProperty('uikit.configuration.name') && project.hasProperty('uikit.binary.location') -} - -private String getBuildTypeForXcode() { - project.properties['uikit.configuration.name'] as String -} - -private File getBinaryLocationForXcode() { - file(project.properties['uikit.binary.location']) -} diff --git a/samples/uikit/build.gradle.kts b/samples/uikit/build.gradle.kts new file mode 100644 index 00000000000..29d9ff200a3 --- /dev/null +++ b/samples/uikit/build.gradle.kts @@ -0,0 +1,111 @@ +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType + +plugins { + kotlin("multiplatform") // version "1.3.60-eap-23" apply true +} + +allprojects { + repositories { + jcenter() + maven("https://dl.bintray.com/kotlin/kotlin-eap") + maven("https://dl.bintray.com/kotlin/kotlin-dev") + } +} + +val sdkName: String? = System.getenv("SDK_NAME") + +enum class Target(val simulator: Boolean, val key: String) { + WATCHOS_X86(true, "watchos"), WATCHOS_ARM64(false, "watchos"), + IOS_X64(true, "ios"), IOS_ARM64(false, "ios") +} + +val target = sdkName.orEmpty().let { + when { + it.startsWith("iphoneos") -> Target.IOS_ARM64 + it.startsWith("iphonesimulator") -> Target.IOS_X64 + it.startsWith("watchos") -> Target.WATCHOS_ARM64 + it.startsWith("watchsimulator") -> Target.WATCHOS_X86 + else -> Target.IOS_X64 + } +} + +val buildType = System.getenv("CONFIGURATION")?.let { + NativeBuildType.valueOf(it.toUpperCase()) +} ?: NativeBuildType.DEBUG + +kotlin { + // Declare a target. + // We declare only one target (either arm64 or x64) + // to workaround lack of common platform libraries + // for both device and simulator. + val ios = if (!target.simulator ) { + // Device. + iosArm64("ios") + } else { + // Simulator. + iosX64("ios") + } + + val watchos = if (!target.simulator) { + // Device. + watchosArm64("watchos") + } else { + // Simulator. + watchosX86("watchos") + } + + // Declare the output program. + ios.binaries.executable(listOf(buildType)) { + baseName = "app" + entryPoint = "sample.uikit.main" + } + + watchos.binaries.executable(listOf(buildType)) { + baseName = "watchapp" + } + + // Configure dependencies. + val appleMain by sourceSets.creating { + dependsOn(sourceSets["commonMain"]) + } + sourceSets["iosMain"].dependsOn(appleMain) + sourceSets["watchosMain"].dependsOn(appleMain) +} + +// Create Xcode integration tasks. +val targetBuildDir: String? = System.getenv("TARGET_BUILD_DIR") +val executablePath: String? = System.getenv("EXECUTABLE_PATH") + +val currentTarget = kotlin.targets[target.key] as KotlinNativeTarget +val kotlinBinary = currentTarget.binaries.getExecutable(buildType) +val xcodeIntegrationGroup = "Xcode integration" + +val packForXCode = if (sdkName == null || targetBuildDir == null || executablePath == null) { + // The build is launched not by Xcode -> + // We cannot create a copy task and just show a meaningful error message. + tasks.create("packForXCode").doLast { + throw IllegalStateException("Please run the task from Xcode") + } +} else { + // Otherwise copy the executable into the Xcode output directory. + tasks.create("packForXCode", Copy::class.java) { + dependsOn(kotlinBinary.linkTask) + + destinationDir = file(targetBuildDir) + + val dsymSource = kotlinBinary.outputFile.absolutePath + ".dSYM" + val dsymDestination = File(executablePath).parentFile.name + ".dSYM" + val oldExecName = kotlinBinary.outputFile.name + val newExecName = File(executablePath).name + + from(dsymSource) { + into(dsymDestination) + rename(oldExecName, newExecName) + } + + from(kotlinBinary.outputFile) { + rename { executablePath } + } + } +} diff --git a/samples/uikit/konan.xcodeproj/project.pbxproj b/samples/uikit/konan.xcodeproj/project.pbxproj deleted file mode 100644 index d6b5f077baf..00000000000 --- a/samples/uikit/konan.xcodeproj/project.pbxproj +++ /dev/null @@ -1,342 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 2CB540471F56C2C4006EE521 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2CB540451F56C2C4006EE521 /* Main.storyboard */; }; - 2CB540491F56C2C4006EE521 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2CB540481F56C2C4006EE521 /* Assets.xcassets */; }; - 2CB5404C1F56C2C4006EE521 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2CB5404A1F56C2C4006EE521 /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 2C33F7F822378402009209E2 /* src */ = {isa = PBXFileReference; lastKnownFileType = folder; path = src; sourceTree = SOURCE_ROOT; }; - 2CB540391F56C2C4006EE521 /* konan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = konan.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 2CB540461F56C2C4006EE521 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 2CB540481F56C2C4006EE521 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 2CB5404B1F56C2C4006EE521 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 2CB5404D1F56C2C4006EE521 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2CB540361F56C2C4006EE521 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 2CB540301F56C2C4006EE521 = { - isa = PBXGroup; - children = ( - 2CB5403B1F56C2C4006EE521 /* konan */, - 2CB5403A1F56C2C4006EE521 /* Products */, - 2CB540531F56CC4D006EE521 /* Frameworks */, - ); - sourceTree = ""; - }; - 2CB5403A1F56C2C4006EE521 /* Products */ = { - isa = PBXGroup; - children = ( - 2CB540391F56C2C4006EE521 /* konan.app */, - ); - name = Products; - sourceTree = ""; - }; - 2CB5403B1F56C2C4006EE521 /* konan */ = { - isa = PBXGroup; - children = ( - 2C33F7F822378402009209E2 /* src */, - 2CB540451F56C2C4006EE521 /* Main.storyboard */, - 2CB540481F56C2C4006EE521 /* Assets.xcassets */, - 2CB5404A1F56C2C4006EE521 /* LaunchScreen.storyboard */, - 2CB5404D1F56C2C4006EE521 /* Info.plist */, - ); - path = konan; - sourceTree = ""; - }; - 2CB540531F56CC4D006EE521 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 2CB540381F56C2C4006EE521 /* konan */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2CB540501F56C2C4006EE521 /* Build configuration list for PBXNativeTarget "konan" */; - buildPhases = ( - 2C901F9C1F5D7074004412FA /* Remove Original Binary */, - 2CB540351F56C2C4006EE521 /* Sources */, - 2CB540361F56C2C4006EE521 /* Frameworks */, - 2C901F991F59928A004412FA /* Build Binary From Kotlin Sources */, - 2CB540371F56C2C4006EE521 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = konan; - productName = konan; - productReference = 2CB540391F56C2C4006EE521 /* konan.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 2CB540311F56C2C4006EE521 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0830; - ORGANIZATIONNAME = JetBrains; - TargetAttributes = { - 2CB540381F56C2C4006EE521 = { - CreatedOnToolsVersion = 8.3.3; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 2CB540341F56C2C4006EE521 /* Build configuration list for PBXProject "konan" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 2CB540301F56C2C4006EE521; - productRefGroup = 2CB5403A1F56C2C4006EE521 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 2CB540381F56C2C4006EE521 /* konan */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 2CB540371F56C2C4006EE521 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2CB5404C1F56C2C4006EE521 /* LaunchScreen.storyboard in Resources */, - 2CB540491F56C2C4006EE521 /* Assets.xcassets in Resources */, - 2CB540471F56C2C4006EE521 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 2C901F991F59928A004412FA /* Build Binary From Kotlin Sources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Build Binary From Kotlin Sources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$SRCROOT/../gradlew\" -p \"$SRCROOT\" buildAppForXcode \\\n-Puikit.preset.name=\"$KOTLIN_NATIVE_PRESET\" \\\n-Puikit.configuration.name=\"$CONFIGURATION\" \\\n-Puikit.binary.location=\"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\n"; - }; - 2C901F9C1F5D7074004412FA /* Remove Original Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Remove Original Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "rm -f \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 2CB540351F56C2C4006EE521 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 2CB540451F56C2C4006EE521 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 2CB540461F56C2C4006EE521 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 2CB5404A1F56C2C4006EE521 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 2CB5404B1F56C2C4006EE521 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 2CB5404E1F56C2C4006EE521 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_BITCODE = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - 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 = 10.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 2CB5404F1F56C2C4006EE521 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_BITCODE = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - 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 = 10.3; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 2CB540511F56C2C4006EE521 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = konan/Info.plist; - "KOTLIN_NATIVE_PRESET[sdk=iphoneos*]" = iosArm64; - "KOTLIN_NATIVE_PRESET[sdk=iphonesimulator*]" = iosX64; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.konan; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 2CB540521F56C2C4006EE521 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = konan/Info.plist; - "KOTLIN_NATIVE_PRESET[sdk=iphoneos*]" = iosArm64; - "KOTLIN_NATIVE_PRESET[sdk=iphonesimulator*]" = iosX64; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.konan; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2CB540341F56C2C4006EE521 /* Build configuration list for PBXProject "konan" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2CB5404E1F56C2C4006EE521 /* Debug */, - 2CB5404F1F56C2C4006EE521 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2CB540501F56C2C4006EE521 /* Build configuration list for PBXNativeTarget "konan" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2CB540511F56C2C4006EE521 /* Debug */, - 2CB540521F56C2C4006EE521 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 2CB540311F56C2C4006EE521 /* Project object */; -} diff --git a/samples/uikit/konan/Assets.xcassets/AppIcon.appiconset/Contents.json b/samples/uikit/konan/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 19882d568af..00000000000 --- a/samples/uikit/konan/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ios-marketing", - "size" : "1024x1024", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/samples/uikit/konan/Base.lproj/LaunchScreen.storyboard b/samples/uikit/konan/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index fdf3f97d1b6..00000000000 --- a/samples/uikit/konan/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/uikit/konan/Base.lproj/Main.storyboard b/samples/uikit/konan/Base.lproj/Main.storyboard deleted file mode 100644 index 416f8e2d688..00000000000 --- a/samples/uikit/konan/Base.lproj/Main.storyboard +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/uikit/konan/Info.plist b/samples/uikit/plists/Ios/Info.plist similarity index 57% rename from samples/uikit/konan/Info.plist rename to samples/uikit/plists/Ios/Info.plist index 38e98af23d3..47ef031b0d2 100644 --- a/samples/uikit/konan/Info.plist +++ b/samples/uikit/plists/Ios/Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -18,21 +18,5 @@ 1.0 CFBundleVersion 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - diff --git a/samples/uikit/project.yml b/samples/uikit/project.yml new file mode 100644 index 00000000000..4ddbbe82abe --- /dev/null +++ b/samples/uikit/project.yml @@ -0,0 +1,28 @@ +name: UIKitSample +options: + bundleIdPrefix: org.jetbrains +settings: + DEVELOPMENT_TEAM: N462MKSJ7M + CODE_SIGN_IDENTITY: "iPhone Developer" + CODE_SIGN_STYLE: Automatic + MARKETING_VERSION: "1.0" + CURRENT_PROJECT_VERSION: "4" + SDKROOT: iphoneos +targets: + UIKitSample: + type: application + platform: iOS + deploymentTarget: "12.0" + prebuildScripts: + - script: cd "$SRCROOT" && ../gradlew -p .. packForXCode + name: GradleCompile + info: + path: plists/Ios/Info.plist + properties: + sources: + - "src/" + settings: + LIBRARY_SEARCH_PATHS: "$(inherited)" + ENABLE_BITCODE: "YES" + ONLY_ACTIVE_ARCH: "NO" + VALID_ARCHS: "arm64" diff --git a/samples/uikit/src/iosMain/kotlin/ViewController.kt b/samples/uikit/src/iosMain/kotlin/ViewController.kt new file mode 100644 index 00000000000..7730f054f0e --- /dev/null +++ b/samples/uikit/src/iosMain/kotlin/ViewController.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package sample.uikit + +import kotlinx.cinterop.* +import platform.Foundation.* +import platform.UIKit.* +import platform.CoreGraphics.CGPointMake +import platform.CoreGraphics.CGRectMake +import platform.Foundation.NSCoder +import platform.Foundation.NSSelectorFromString + +@ExportObjCClass +class ViewController : UIViewController { + + @OverrideInit + constructor() : super(nibName = null, bundle = null) + + @OverrideInit + constructor(coder: NSCoder) : super(coder) + + @ObjCOutlet + lateinit var label: UILabel + + @ObjCOutlet + lateinit var button: UIButton + + var pressed = 0 + + @ObjCAction + fun buttonPressed() { + label.text = "Hello #${pressed++} from Konan!" + println("Button pressed") + } + + override fun viewDidLoad() { + super.viewDidLoad() + + val (width, height) = UIScreen.mainScreen.bounds.useContents { + this.size.width to this.size.height + } + + val header = UIView().apply { + backgroundColor = UIColor.lightGrayColor + view.addSubview(this) + translatesAutoresizingMaskIntoConstraints = false + leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true + topAnchor.constraintEqualToAnchor(view.topAnchor).active = true + widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true + heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true + } + + label = UILabel().apply { + setFrame(CGRectMake(x = 10.0, y = 10.0, width = width - 100.0, height = 40.0)) + center = CGPointMake(x = width / 2, y = 40.0 ) + textAlignment = NSTextAlignmentCenter + text = "Press OK" + header.addSubview(this) + } + + button = UIButton().apply { + setFrame(CGRectMake(x = 10.0, y = height - 100.0, width = width - 100.0, height = 40.0)) + center = CGPointMake(x = width / 2, y = height / 2) + backgroundColor = UIColor.blueColor + setTitle("OK", forState = UIControlStateNormal) + font = UIFont.fontWithName(fontName = font.fontName, size = 28.0)!! + layer.borderWidth = 1.0 + layer.borderColor = UIColor.colorWithRed(0x47 / 255.0, 0x43 / 255.0, 0x70 / 255.0, 1.0).CGColor + layer.masksToBounds = true + addTarget(target = this@ViewController, action = NSSelectorFromString("buttonPressed"), + forControlEvents = UIControlEventTouchUpInside) + header.addSubview(this) + } + + } +} diff --git a/samples/uikit/src/iosMain/kotlin/main.kt b/samples/uikit/src/iosMain/kotlin/main.kt index f60a3a5c623..65e37af259e 100644 --- a/samples/uikit/src/iosMain/kotlin/main.kt +++ b/samples/uikit/src/iosMain/kotlin/main.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ @@ -21,32 +21,21 @@ fun main(args: Array) { } class AppDelegate : UIResponder, UIApplicationDelegateProtocol { - - @OverrideInit constructor() : super() - companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta {} + @OverrideInit + constructor() : super() + private var _window: UIWindow? = null override fun window() = _window - override fun setWindow(window: UIWindow?) { _window = window } -} + override fun setWindow(window: UIWindow?) { + _window = window + } -@ExportObjCClass -class ViewController : UIViewController { - - @OverrideInit constructor(coder: NSCoder) : super(coder) - - @ObjCOutlet - lateinit var label: UILabel - - @ObjCOutlet - lateinit var textField: UITextField - - @ObjCOutlet - lateinit var button: UIButton - - @ObjCAction - fun buttonPressed() { - label.text = "Konan says: 'Hello, ${textField.text}!'" + override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map?): Boolean { + window = UIWindow(frame = UIScreen.mainScreen.bounds) + window!!.rootViewController = ViewController() + window!!.makeKeyAndVisible() + return true } } diff --git a/samples/watchos/README.md b/samples/watchos/README.md new file mode 100644 index 00000000000..fd49ffdfc8a --- /dev/null +++ b/samples/watchos/README.md @@ -0,0 +1,24 @@ +# watchOS sample + +This example shows how to write watchOS UI applications in Kotlin, and run them on +iWatch or simulator. + +To build and run the sample do the following: + +1. Open `watchosSample.xcodeproj` set development team to your own and make bundle ID unique + in project setting. + or +1a. Similarly modify `bundleIdPrefix`, `DEVELOPMENT_TEAM` and `WKAppBundleIdentifier` in `project.yml` + and generate Xcode project with `xcodegen` (https://github.com/yonaskolb/XcodeGen/). + Open generated `watchosSample.xcodeproj` with Xcode. + +2. Update property `WKAppBundleIdentifier` in `plists/Ext/Info.plist` with new ID of the watch application, + if not regenerating project. + +3. Now build and run the application on a connected iPhone with paired iWatch or simulator. + +Note that in this example we do not use storyboards, and instead create user interface +components programmatically. + +First run of application on the physical watch could be blocked, so run it from watch menu +and explicitly confirm that developer is trusted. diff --git a/samples/watchos/Storyboard.storyboard b/samples/watchos/Storyboard.storyboard new file mode 100644 index 00000000000..6e06c6f0b18 --- /dev/null +++ b/samples/watchos/Storyboard.storyboard @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/samples/watchos/build.gradle.kts b/samples/watchos/build.gradle.kts new file mode 100644 index 00000000000..ff97e53cf85 --- /dev/null +++ b/samples/watchos/build.gradle.kts @@ -0,0 +1,110 @@ +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType + +plugins { + kotlin("multiplatform") // version "1.3.60-eap-23" apply true +} + +allprojects { + repositories { + jcenter() + maven("https://dl.bintray.com/kotlin/kotlin-eap") + maven("https://dl.bintray.com/kotlin/kotlin-dev") + } +} + +val sdkName: String? = System.getenv("SDK_NAME") + +enum class Target(val simulator: Boolean, val key: String) { + WATCHOS_X86(true, "watchos"), WATCHOS_ARM64(false, "watchos"), + IOS_X64(true, "ios"), IOS_ARM64(false, "ios") +} + +val target = sdkName.orEmpty().let { + when { + it.startsWith("iphoneos") -> Target.IOS_ARM64 + it.startsWith("iphonesimulator") -> Target.IOS_X64 + it.startsWith("watchos") -> Target.WATCHOS_ARM64 + it.startsWith("watchsimulator") -> Target.WATCHOS_X86 + else -> Target.WATCHOS_X86 + } +} + +val buildType = System.getenv("CONFIGURATION")?.let { + NativeBuildType.valueOf(it.toUpperCase()) +} ?: NativeBuildType.DEBUG + +kotlin { + // Declare a target. + // We declare only one target (either arm64 or x64) + // to workaround lack of common platform libraries + // for both device and simulator. + val ios = if (!target.simulator ) { + // Device. + iosArm64("ios") + } else { + // Simulator. + iosX64("ios") + } + + val watchos = if (!target.simulator) { + // Device. + watchosArm64("watchos") + } else { + // Simulator. + watchosX86("watchos") + } + + // Declare the output program. + ios.binaries.executable(listOf(buildType)) { + baseName = "app" + } + + watchos.binaries.executable(listOf(buildType)) { + baseName = "watchapp" + entryPoint = "sample.watchos.main" + } + + // Configure dependencies. + val appleMain by sourceSets.creating { + dependsOn(sourceSets["commonMain"]) + } + + sourceSets["iosMain"].dependsOn(appleMain) + sourceSets["watchosMain"].dependsOn(appleMain) +} + +// Create Xcode integration tasks. +val targetBuildDir: String? = System.getenv("TARGET_BUILD_DIR") +val executablePath: String? = System.getenv("EXECUTABLE_PATH") + +val currentTarget = kotlin.targets[target.key] as KotlinNativeTarget +val kotlinBinary = currentTarget.binaries.getExecutable(buildType) +val xcodeIntegrationGroup = "Xcode integration" + +val packForXCode = if (sdkName == null || targetBuildDir == null || executablePath == null) { + // The build is launched not by Xcode -> + // We cannot create a copy task and just show a meaningful error message. + tasks.create("packForXCode").doLast { + throw IllegalStateException("Please run the task from Xcode") + } +} else { + // Otherwise copy the executable into the Xcode output directory. + tasks.create("packForXCode", Copy::class.java) { + dependsOn(kotlinBinary.linkTask) + destinationDir = file(targetBuildDir) + val dsymSource = kotlinBinary.outputFile.absolutePath + ".dSYM" + val dsymDestination = file(executablePath).parentFile.name + ".dSYM" + val oldExecName = kotlinBinary.outputFile.name + val newExecName = file(executablePath).name + + from(dsymSource) { + into(dsymDestination) + rename(oldExecName, newExecName) + } + + from(kotlinBinary.outputFile) { + rename { executablePath } + } + } +} diff --git a/samples/watchos/plists/App/Info.plist b/samples/watchos/plists/App/Info.plist new file mode 100644 index 00000000000..c71ba11bef4 --- /dev/null +++ b/samples/watchos/plists/App/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + WKWatchKitApp + + + diff --git a/samples/watchos/plists/App/Interface.plist b/samples/watchos/plists/App/Interface.plist new file mode 100644 index 00000000000..45ad43f8ea9 --- /dev/null +++ b/samples/watchos/plists/App/Interface.plist @@ -0,0 +1,16 @@ + + + + + controllers + + controller-AgC-eL-Hgc + + controllerClass + Watchapp3InterfaceController + + + root + controller-AgC-eL-Hgc + + diff --git a/samples/watchos/plists/Ext/Info.plist b/samples/watchos/plists/Ext/Info.plist new file mode 100644 index 00000000000..37fc21d2eea --- /dev/null +++ b/samples/watchos/plists/Ext/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionAttributes + + WKAppBundleIdentifier + com.jetbrains.watchapp0.watchapp3.watchkitapp + + NSExtensionPointIdentifier + com.apple.watchkit + + WKExtensionDelegateClassName + Watchapp3ExtensionDelegate + WKWatchOnly + + + diff --git a/samples/watchos/project.yml b/samples/watchos/project.yml new file mode 100644 index 00000000000..568536cc50d --- /dev/null +++ b/samples/watchos/project.yml @@ -0,0 +1,54 @@ +name: watchosSample +options: + bundleIdPrefix: com.jetbrains.watchapp0 +settings: + DEVELOPMENT_TEAM: N462MKSJ7M + CODE_SIGN_IDENTITY: "iPhone Developer" + CODE_SIGN_STYLE: Automatic + MARKETING_VERSION: "1.0" + CURRENT_PROJECT_VERSION: "4" + SDKROOT: iphoneos +targets: + watchapp3.watchkitapp.watchkitextension: + type: watchkit2-extension + platform: watchOS + sources: + - "plists/Ext" + - "src/" + prebuildScripts: + - script: cd "$SRCROOT" && ../gradlew -p .. packForXCode + name: GradleCompile + info: + path: plists/Ext/Info.plist + properties: + WKWatchOnly: true + CFBundleShortVersionString: $(MARKETING_VERSION) + CFBundleVersion: $(CURRENT_PROJECT_VERSION) + WKExtensionDelegateClassName: Watchapp3ExtensionDelegate + NSExtension: + NSExtensionAttributes: + WKAppBundleIdentifier: com.jetbrains.watchapp0.watchapp3.watchkitapp + NSExtensionPointIdentifier: com.apple.watchkit + watchapp3.watchkitapp: + type: application.watchapp2 + platform: watchOS + dependencies: + - target: "watchapp3.watchkitapp.watchkitextension" + sources: + - "plists/App" + - "plists/App/Interface.plist" + info: + path: plists/App/Info.plist + properties: + WKWatchKitApp: true + CFBundleShortVersionString: $(MARKETING_VERSION) + CFBundleVersion: $(CURRENT_PROJECT_VERSION) + settings: + ENABLE_BITCODE: "YES" + ONLY_ACTIVE_ARCH: "YES" + VALID_ARCHS: $(ARCHS_STANDARD) + watchapp3: + type: application.watchapp2-container + platform: iOS + dependencies: + - target: "watchapp3.watchkitapp" diff --git a/samples/watchos/src/watchosMain/kotlin/main.kt b/samples/watchos/src/watchosMain/kotlin/main.kt new file mode 100644 index 00000000000..8637772d393 --- /dev/null +++ b/samples/watchos/src/watchosMain/kotlin/main.kt @@ -0,0 +1,64 @@ +/* +* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license +* that can be found in the license/LICENSE.txt file. +*/ + +package sample.watchos + +import kotlinx.cinterop.* +import platform.Foundation.* +import platform.WatchKit.* +import platform.darwin.NSObject + +// Standard entry point for WatchKit applications. +@SymbolName("WKExtensionMain") +external fun WKExtensionMain(argc: Int, argv: CPointer>) + +fun main(args: Array) { + memScoped { + val argc = args.size + 1 + val argv = (arrayOf("konan") + args).map { it.cstr.ptr }.toCValues() + + autoreleasepool { + WKExtensionMain(argc, argv.ptr) + } + } +} + +// Name of this class is mentioned in Info.plist. +@ExportObjCClass +@Suppress("CONFLICTING_OVERLOADS") +class Watchapp3ExtensionDelegate : NSObject, WKExtensionDelegateProtocol { + + @OverrideInit constructor() : super() { + println("constructor Watchapp3ExtensionDelegate") + } + + override fun applicationDidFinishLaunching() { + println("applicationDidFinishLaunching") + } +} + +// Name of this class is mentioned in Interface.plist. +@ExportObjCClass +class Watchapp3InterfaceController : WKInterfaceController { + @OverrideInit constructor() : super() { + println("constructor Watchapp3InterfaceController") + } + + override fun didAppear() { + println("didAppear") + presentTextInputControllerWithSuggestions(null, WKTextInputMode.WKTextInputModeAllowAnimatedEmoji) { + results -> + println("printed $results") + } + } + + override fun awakeWithContext(context: Any?) { + super.awakeWithContext(context) + println("awakeWithContext $context") + if (context == null) { + setTitle("Kotlin/Native sample") + } + } +} diff --git a/samples/watchos/watchosSample.xcodeproj/project.pbxproj b/samples/watchos/watchosSample.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..f8679d28afc --- /dev/null +++ b/samples/watchos/watchosSample.xcodeproj/project.pbxproj @@ -0,0 +1,519 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 2E2A2A9B9037D7A4B8891638 /* Interface.plist in Resources */ = {isa = PBXBuildFile; fileRef = BA63A983DA7F116016C945B1 /* Interface.plist */; }; + 465E1456E1F3939248A1AE18 /* watchapp3.watchkitapp.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = C83F8D8D7FEC0305A3C42EF0 /* watchapp3.watchkitapp.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + C413044D6EC06F630A1281B6 /* watchapp3.watchkitapp.watchkitextension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = D8268FB6509819F8DF88F338 /* watchapp3.watchkitapp.watchkitextension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 50B1D2FDA42D7325321EAF92 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CF674FA31D0C7A5F482A25CD /* Project object */; + proxyType = 1; + remoteGlobalIDString = 85F30E635DAD8136EC80F430; + remoteInfo = watchapp3.watchkitapp.watchkitextension; + }; + 777F9D95E28CDA6B3DB73D90 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CF674FA31D0C7A5F482A25CD /* Project object */; + proxyType = 1; + remoteGlobalIDString = C432419F771BBC1164EFD4F4; + remoteInfo = watchapp3.watchkitapp; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 4E503C8039A14A5EA90C75B2 /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + C413044D6EC06F630A1281B6 /* watchapp3.watchkitapp.watchkitextension.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + B00C7BBEEE4BC6B46F93C76A /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + 465E1456E1F3939248A1AE18 /* watchapp3.watchkitapp.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 6CC853D0EA8F64CF953D56AD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 70938E1058DAC99B6ACB89A1 /* watchapp3.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = watchapp3.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AA40AB18A1134B1A4F332C2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BA63A983DA7F116016C945B1 /* Interface.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Interface.plist; sourceTree = ""; }; + C83F8D8D7FEC0305A3C42EF0 /* watchapp3.watchkitapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = watchapp3.watchkitapp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D8268FB6509819F8DF88F338 /* watchapp3.watchkitapp.watchkitextension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = watchapp3.watchkitapp.watchkitextension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 3935909E94CECE9E5D5E428A /* Products */ = { + isa = PBXGroup; + children = ( + 70938E1058DAC99B6ACB89A1 /* watchapp3.app */, + C83F8D8D7FEC0305A3C42EF0 /* watchapp3.watchkitapp.app */, + D8268FB6509819F8DF88F338 /* watchapp3.watchkitapp.watchkitextension.appex */, + ); + name = Products; + sourceTree = ""; + }; + ADD17C1426885B036B4D4500 = { + isa = PBXGroup; + children = ( + BBACCDB231253BE6BD60C83F /* App */, + E7C757434B0E5A8C26D64165 /* Ext */, + 3935909E94CECE9E5D5E428A /* Products */, + ); + sourceTree = ""; + }; + BBACCDB231253BE6BD60C83F /* App */ = { + isa = PBXGroup; + children = ( + 6CC853D0EA8F64CF953D56AD /* Info.plist */, + BA63A983DA7F116016C945B1 /* Interface.plist */, + ); + name = App; + path = plists/App; + sourceTree = ""; + }; + E7C757434B0E5A8C26D64165 /* Ext */ = { + isa = PBXGroup; + children = ( + 7AA40AB18A1134B1A4F332C2 /* Info.plist */, + ); + name = Ext; + path = plists/Ext; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 85F30E635DAD8136EC80F430 /* watchapp3.watchkitapp.watchkitextension */ = { + isa = PBXNativeTarget; + buildConfigurationList = E590E047549EA79901895875 /* Build configuration list for PBXNativeTarget "watchapp3.watchkitapp.watchkitextension" */; + buildPhases = ( + ED480B935D153474B4BE5E66 /* GradleCompile */, + F1E62571296D41A29073A0DC /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = watchapp3.watchkitapp.watchkitextension; + productName = watchapp3.watchkitapp.watchkitextension; + productReference = D8268FB6509819F8DF88F338 /* watchapp3.watchkitapp.watchkitextension.appex */; + productType = "com.apple.product-type.watchkit2-extension"; + }; + C2A3BDB9D8B1B6F53A29A1DE /* watchapp3 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9FC8F6F94AA3C978F239A5AC /* Build configuration list for PBXNativeTarget "watchapp3" */; + buildPhases = ( + 64396ECFF63C36B1C586BC70 /* Sources */, + B00C7BBEEE4BC6B46F93C76A /* Embed Watch Content */, + ); + buildRules = ( + ); + dependencies = ( + 1D2B97A46A6DF0B1A5F835FC /* PBXTargetDependency */, + ); + name = watchapp3; + productName = watchapp3; + productReference = 70938E1058DAC99B6ACB89A1 /* watchapp3.app */; + productType = "com.apple.product-type.application.watchapp2-container"; + }; + C432419F771BBC1164EFD4F4 /* watchapp3.watchkitapp */ = { + isa = PBXNativeTarget; + buildConfigurationList = F10C79A6F81EA8DC928F5411 /* Build configuration list for PBXNativeTarget "watchapp3.watchkitapp" */; + buildPhases = ( + 5545C689631BCCAF2B3AF567 /* Sources */, + 1C155B15CD6523CC1566092A /* Resources */, + 4E503C8039A14A5EA90C75B2 /* Embed App Extensions */, + ); + buildRules = ( + ); + dependencies = ( + AF975C9937185BABD014C388 /* PBXTargetDependency */, + ); + name = watchapp3.watchkitapp; + productName = watchapp3.watchkitapp; + productReference = C83F8D8D7FEC0305A3C42EF0 /* watchapp3.watchkitapp.app */; + productType = "com.apple.product-type.application.watchapp2"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + CF674FA31D0C7A5F482A25CD /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + TargetAttributes = { + 85F30E635DAD8136EC80F430 = { + DevelopmentTeam = N462MKSJ7M; + ProvisioningStyle = Automatic; + }; + C2A3BDB9D8B1B6F53A29A1DE = { + DevelopmentTeam = N462MKSJ7M; + ProvisioningStyle = Automatic; + }; + C432419F771BBC1164EFD4F4 = { + DevelopmentTeam = N462MKSJ7M; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = DAC5D137D023645E8075D0A0 /* Build configuration list for PBXProject "watchosSample" */; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = ADD17C1426885B036B4D4500; + projectDirPath = ""; + projectRoot = ""; + targets = ( + C2A3BDB9D8B1B6F53A29A1DE /* watchapp3 */, + C432419F771BBC1164EFD4F4 /* watchapp3.watchkitapp */, + 85F30E635DAD8136EC80F430 /* watchapp3.watchkitapp.watchkitextension */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1C155B15CD6523CC1566092A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2E2A2A9B9037D7A4B8891638 /* Interface.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + ED480B935D153474B4BE5E66 /* GradleCompile */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = GradleCompile; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$SRCROOT\" && ../gradlew -p .. packForXCode"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5545C689631BCCAF2B3AF567 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64396ECFF63C36B1C586BC70 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F1E62571296D41A29073A0DC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 1D2B97A46A6DF0B1A5F835FC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C432419F771BBC1164EFD4F4 /* watchapp3.watchkitapp */; + targetProxy = 777F9D95E28CDA6B3DB73D90 /* PBXContainerItemProxy */; + }; + AF975C9937185BABD014C388 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 85F30E635DAD8136EC80F430 /* watchapp3.watchkitapp.watchkitextension */; + targetProxy = 50B1D2FDA42D7325321EAF92 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 42683BF037EF7F48F88A88E6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + 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_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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 4; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = N462MKSJ7M; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + 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; + MARKETING_VERSION = 1.0; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_VERSION = 5.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 955A76A7B52DD667863D8504 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.jetbrains.watchapp0.watchapp3; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 964D5540C94A88A9C7443DC0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ENABLE_BITCODE = YES; + INFOPLIST_FILE = plists/App/Info.plist; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.jetbrains.watchapp0.watchapp3.watchkitapp; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + VALID_ARCHS = "$(ARCHS_STANDARD)"; + }; + name = Debug; + }; + AA41209F69F829E248A0B3BC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + 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_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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 4; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = N462MKSJ7M; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + ); + 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; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + B7ECDB01F700B2FCF22D16A4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ENABLE_BITCODE = YES; + INFOPLIST_FILE = plists/App/Info.plist; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.jetbrains.watchapp0.watchapp3.watchkitapp; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + VALID_ARCHS = "$(ARCHS_STANDARD)"; + }; + name = Release; + }; + BE4BD7149295C555AB8E7434 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + INFOPLIST_FILE = plists/Ext/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.jetbrains.watchapp0.watchapp3.watchkitapp.watchkitextension; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + }; + name = Debug; + }; + E5DC67A24A9D438C35262109 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + INFOPLIST_FILE = plists/Ext/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.jetbrains.watchapp0.watchapp3.watchkitapp.watchkitextension; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + }; + name = Release; + }; + F4338EEF3126A85F45205463 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.jetbrains.watchapp0.watchapp3; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9FC8F6F94AA3C978F239A5AC /* Build configuration list for PBXNativeTarget "watchapp3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F4338EEF3126A85F45205463 /* Debug */, + 955A76A7B52DD667863D8504 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ""; + }; + DAC5D137D023645E8075D0A0 /* Build configuration list for PBXProject "watchosSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AA41209F69F829E248A0B3BC /* Debug */, + 42683BF037EF7F48F88A88E6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + E590E047549EA79901895875 /* Build configuration list for PBXNativeTarget "watchapp3.watchkitapp.watchkitextension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BE4BD7149295C555AB8E7434 /* Debug */, + E5DC67A24A9D438C35262109 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ""; + }; + F10C79A6F81EA8DC928F5411 /* Build configuration list for PBXNativeTarget "watchapp3.watchkitapp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 964D5540C94A88A9C7443DC0 /* Debug */, + B7ECDB01F700B2FCF22D16A4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ""; + }; +/* End XCConfigurationList section */ + }; + rootObject = CF674FA31D0C7A5F482A25CD /* Project object */; +} diff --git a/samples/watchos/watchosSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/samples/watchos/watchosSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..919434a6254 --- /dev/null +++ b/samples/watchos/watchosSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/samples/watchos/watchosSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/samples/watchos/watchosSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000..18d981003d6 --- /dev/null +++ b/samples/watchos/watchosSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + +