├── .gitignore ├── .idea └── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── README.md ├── android ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── aakira │ │ └── multithreadmpp │ │ └── MainActivity.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ └── activity_main.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── network_security_config.xml ├── arts └── architecture.jpeg ├── build.gradle.kts ├── buildSrc ├── .gitignore ├── build.gradle.kts └── src │ └── main │ └── kotlin │ └── config │ └── Dep.kt ├── common ├── .gitignore ├── build.gradle.kts └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ └── com │ │ └── github │ │ └── aakira │ │ └── multithreadmpp │ │ └── common │ │ ├── db │ │ └── DbActual.kt │ │ └── util │ │ └── ThreadUtilActual.kt │ ├── commonMain │ ├── kotlin │ │ └── com │ │ │ └── github │ │ │ └── aakira │ │ │ └── multithreadmpp │ │ │ └── common │ │ │ ├── GreetingService.kt │ │ │ ├── db │ │ │ └── GreetingDao.kt │ │ │ ├── model │ │ │ └── Greeting.kt │ │ │ └── util │ │ │ ├── FlowUtil.kt │ │ │ └── ThreadUtil.kt │ └── sqldelight │ │ └── com │ │ └── github │ │ └── aakira │ │ └── multithreadmpp │ │ └── db │ │ └── Greeting.sq │ └── iosMain │ ├── AndroidManifest.xml │ └── kotlin │ └── com │ └── github │ └── aakira │ └── multithreadmpp │ └── common │ ├── GreetingService.kt │ ├── db │ └── DbActual.kt │ └── util │ └── ThreadUtil.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── ios ├── ios.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── aakira.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── aakira.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist └── ios │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift └── settings.gradle.kts /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea/* 5 | !/.idea/codeStyles/ 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | .cxx 11 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 14 | 15 | 16 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | xmlns:android 25 | 26 | ^$ 27 | 28 | 29 | 30 |
31 |
32 | 33 | 34 | 35 | xmlns:.* 36 | 37 | ^$ 38 | 39 | 40 | BY_NAME 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:id 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | .*:name 59 | 60 | http://schemas.android.com/apk/res/android 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | name 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | style 81 | 82 | ^$ 83 | 84 | 85 | 86 |
87 |
88 | 89 | 90 | 91 | .* 92 | 93 | ^$ 94 | 95 | 96 | BY_NAME 97 | 98 |
99 |
100 | 101 | 102 | 103 | .* 104 | 105 | http://schemas.android.com/apk/res/android 106 | 107 | 108 | ANDROID_ATTRIBUTE_ORDER 109 | 110 |
111 |
112 | 113 | 114 | 115 | .* 116 | 117 | .* 118 | 119 | 120 | BY_NAME 121 | 122 |
123 |
124 |
125 |
126 | 127 | 129 |
130 |
-------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kotlin MPP Multithread Architecture 2 | 3 | ![architecture](/arts/architecture.jpeg) 4 | 5 | This is the best architecture of Kotlin Multiplatform Project I think!(It's a Japanese joke) 6 | This project works on background thread using kotlinx.Coroutines. 7 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | import config.Dep 2 | import config.Versions 3 | 4 | plugins { 5 | id 'com.android.application' 6 | id 'kotlin-android' 7 | id 'kotlin-android-extensions' 8 | } 9 | 10 | android { 11 | compileSdkVersion Versions.compileSdkVersion 12 | buildToolsVersion Versions.buildToolsVersion 13 | 14 | defaultConfig { 15 | minSdkVersion Versions.minSdkVersion 16 | targetSdkVersion Versions.targetSdkVersion 17 | versionCode Versions.mobileVersionCode as int 18 | versionName Versions.mobileVersionName 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | packagingOptions { 27 | exclude 'META-INF/kotlinx-io.kotlin_module' 28 | exclude 'META-INF/kotlinx-serialization-runtime.kotlin_module' 29 | exclude 'META-INF/kotlinx-coroutines-core.kotlin_module' 30 | exclude 'META-INF/kotlinx-coroutines-io.kotlin_module' 31 | exclude 'META-INF/atomicfu.kotlin_module' 32 | exclude 'META-INF/ktor-http.kotlin_module' 33 | exclude 'META-INF/ktor-client-core.kotlin_module' 34 | exclude 'META-INF/ktor-client-json.kotlin_module' 35 | exclude 'META-INF/ktor-client-logging.kotlin_module' 36 | exclude 'META-INF/ktor-client-logging-core.kotlin_module' 37 | exclude 'META-INF/ktor-client-serialization.kotlin_module' 38 | exclude 'META-INF/ktor-utils.kotlin_module' 39 | exclude 'META-INF/ktor-http-cio.kotlin_module' 40 | exclude 'META-INF/sqldelight-sqlite-driver.kotlin_module' 41 | } 42 | } 43 | 44 | dependencies { 45 | implementation project(":common") 46 | 47 | implementation Dep.Kotlin.jvm 48 | implementation Dep.AndroidX.appCompat 49 | implementation Dep.AndroidX.coreKtx 50 | implementation Dep.AndroidX.constraintLayout 51 | implementation Dep.AndroidX.runtimeKtx 52 | } 53 | -------------------------------------------------------------------------------- /android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle.kts.bak. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/aakira/multithreadmpp/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp 2 | 3 | import android.os.Bundle 4 | import android.util.Log 5 | import androidx.appcompat.app.AppCompatActivity 6 | import androidx.lifecycle.lifecycleScope 7 | import com.github.aakira.multithreadmpp.common.GreetingService 8 | import com.github.aakira.multithreadmpp.common.db.mppAppContext 9 | import kotlinx.android.synthetic.main.activity_main.* 10 | import kotlinx.coroutines.flow.catch 11 | import kotlinx.coroutines.flow.launchIn 12 | import kotlinx.coroutines.flow.onEach 13 | 14 | class MainActivity : AppCompatActivity() { 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setContentView(R.layout.activity_main) 19 | 20 | // initialize mpp 21 | mppAppContext = this.applicationContext 22 | 23 | val service = GreetingService() 24 | // store value 25 | service.saveGreetings("Hello") 26 | // observe db value 27 | service.getGreetings() 28 | .onEach { query -> 29 | Log.v("Android", "Android Main Thread: ${Thread.currentThread().name}") 30 | query.executeAsList().firstOrNull()?.let { 31 | helloText.text = it.hello 32 | } 33 | } 34 | .catch { 35 | helloText.text = it.toString() 36 | } 37 | .launchIn(lifecycleScope) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /android/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 9 | 15 | 16 | 23 | 27 | 31 | 32 | 33 | 34 | 41 | 42 | -------------------------------------------------------------------------------- /android/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 13 | 19 | 25 | 31 | 37 | 43 | 49 | 55 | 61 | 67 | 73 | 79 | 85 | 91 | 97 | 103 | 109 | 115 | 121 | 127 | 133 | 139 | 145 | 151 | 157 | 163 | 169 | 175 | 181 | 187 | 193 | 199 | 205 | 206 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /android/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MultithreadMpp 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /android/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10.0.2.2 5 | 6 | -------------------------------------------------------------------------------- /arts/architecture.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/arts/architecture.jpeg -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenLocal() 4 | google() 5 | jcenter() 6 | maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") 7 | } 8 | dependencies { 9 | classpath(config.Dep.BuildPlugins.androidTools) 10 | classpath(config.Dep.BuildPlugins.kotlinGradlePlugin) 11 | classpath(config.Dep.BuildPlugins.sqlDelightMT) 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | google() 19 | jcenter() 20 | maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") 21 | } 22 | } 23 | 24 | tasks.register("clean") { 25 | delete(rootProject.buildDir) 26 | } 27 | -------------------------------------------------------------------------------- /buildSrc/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `kotlin-dsl` 3 | } 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | kotlinDslPluginOptions { 11 | experimentalWarning.set(false) 12 | } -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/config/Dep.kt: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | object Versions { 4 | const val mobileVersionCode = 1 5 | const val mobileVersionName = "1.0.0" 6 | 7 | const val compileSdkVersion = 28 8 | const val minSdkVersion = 21 9 | const val targetSdkVersion = 28 10 | const val buildToolsVersion = "28.0.3" 11 | } 12 | 13 | object Dep { 14 | 15 | const val kotlin_version = "1.3.61" 16 | private const val sql_delight_version = "1.2.1" 17 | private const val sql_delight_mt_version = "1.3.0-mt2-SNAPSHOT" 18 | 19 | object Kotlin { 20 | const val jvm = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 21 | const val common = "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version" 22 | const val js = "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version" 23 | } 24 | 25 | object BuildPlugins { 26 | const val androidTools = "com.android.tools.build:gradle:3.5.2" 27 | const val kotlinGradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 28 | const val serialization = "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" 29 | const val sqlDelight = "com.squareup.sqldelight:gradle-plugin:$sql_delight_version" 30 | const val sqlDelightMT = "co.touchlab.sqldelight:gradle-plugin:$sql_delight_mt_version" 31 | } 32 | 33 | object Serialization { 34 | private const val version = "0.14.0" 35 | const val runtime = "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$version" 36 | const val common = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$version" 37 | const val native = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$version" 38 | const val js = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$version" 39 | } 40 | 41 | object Coroutines { 42 | private const val version = "1.3.3-native-mt" 43 | const val core = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version" 44 | const val common = "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$version" 45 | const val native = "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$version" 46 | const val android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version" 47 | const val js = "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$version" 48 | } 49 | 50 | object Ktor { 51 | private const val client_version = "1.2.6" 52 | const val clientCore = "io.ktor:ktor-client-core:$client_version" 53 | const val clientJson = "io.ktor:ktor-client-gson:$client_version" 54 | const val clientAndroid = "io.ktor:ktor-client-android:$client_version" 55 | const val clientJvm = "io.ktor:ktor-client-core-jvm:$client_version" 56 | const val clientJsonJvm = "io.ktor:ktor-client-json-jvm:$client_version" 57 | const val clientIos = "io.ktor:ktor-client-ios:$client_version" 58 | const val clientJsonIos = "io.ktor:ktor-client-json-native:$client_version" 59 | const val clientJs = "io.ktor:ktor-client-js:$client_version" 60 | const val clientJsonJs = "io.ktor:ktor-client-json-js:$client_version" 61 | 62 | object Serialization { 63 | const val core = "io.ktor:ktor-client-serialization:$client_version" 64 | const val native = "io.ktor:ktor-client-serialization-native:$client_version" 65 | const val jvm = "io.ktor:ktor-client-serialization-jvm:$client_version" 66 | } 67 | } 68 | 69 | object SQLDelight { 70 | const val android = "com.squareup.sqldelight:android-driver:$sql_delight_version" 71 | const val native = "com.squareup.sqldelight:native-driver:$sql_delight_version" 72 | const val jvm = "com.squareup.sqldelight:sqlite-driver:$sql_delight_version" 73 | } 74 | 75 | object SQLDelightMT { 76 | const val runtime = "co.touchlab.sqldelight:runtime:$sql_delight_mt_version" 77 | const val android = "co.touchlab.sqldelight:android-driver:$sql_delight_mt_version" 78 | const val ios = "co.touchlab.sqldelight:ios-driver:$sql_delight_mt_version" 79 | const val jvm = "co.touchlab.sqldelight:sqlite-driver:$sql_delight_mt_version" 80 | const val coroutinesExt = 81 | "co.touchlab.sqldelight:coroutines-extensions:$sql_delight_mt_version" 82 | } 83 | 84 | object AndroidX { 85 | private const val appcompatVersion = "1.1.0" 86 | private const val coreVersion = "1.2.0-beta01" 87 | private const val lifecycleVersion = "2.2.0-rc01" 88 | private const val constraintLayoutVersion = "2.0.0-beta2" 89 | 90 | const val appCompat = "androidx.appcompat:appcompat:$appcompatVersion" 91 | const val coreKtx = "androidx.core:core-ktx:$coreVersion" 92 | 93 | const val service = "androidx.lifecycle:lifecycle-service:$lifecycleVersion" 94 | const val liveDataKtx = "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" 95 | const val runtimeKtx = "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion" 96 | 97 | const val constraintLayout = 98 | "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /common/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import config.Dep 2 | import config.Versions 3 | 4 | plugins { 5 | kotlin("multiplatform") 6 | id("com.android.library") 7 | id("com.squareup.sqldelight") 8 | } 9 | 10 | val frameworkName = "common" 11 | val ideaActive = System.getProperty("idea.active") == "true" 12 | 13 | sqldelight { 14 | database("GreetingDatabase") { 15 | packageName = "com.github.aakira.multithreadmpp.db" 16 | sourceFolders = listOf("sqldelight") 17 | } 18 | linkSqlite = false 19 | } 20 | 21 | kotlin { 22 | android() 23 | 24 | val iosArm32 = iosArm32("iosArm32") 25 | val iosArm64 = iosArm64("iosArm64") 26 | val iosX64 = iosX64("iosX64") 27 | 28 | if (ideaActive) { 29 | iosX64("ios") 30 | } 31 | 32 | sourceSets { 33 | commonMain { 34 | dependencies { 35 | implementation(Dep.Kotlin.common) 36 | implementation(Dep.Coroutines.common) 37 | implementation(Dep.SQLDelightMT.runtime) 38 | } 39 | } 40 | 41 | val androidMain by getting { 42 | dependencies { 43 | implementation(Dep.Kotlin.jvm) 44 | implementation(Dep.Coroutines.android) 45 | implementation(Dep.SQLDelightMT.android) 46 | } 47 | } 48 | 49 | val iosMain = if (ideaActive) getByName("iosMain") else create("iosMain") 50 | 51 | iosMain.dependencies { 52 | implementation(Dep.Coroutines.native) 53 | implementation(Dep.SQLDelightMT.ios) 54 | } 55 | 56 | val iosArm32Main by getting 57 | val iosArm64Main by getting 58 | val iosX64Main by getting 59 | 60 | configure(listOf(iosArm32Main, iosArm64Main, iosX64Main)) { 61 | dependsOn(iosMain) 62 | } 63 | } 64 | 65 | configure(listOf(iosArm32, iosArm64, iosX64)) { 66 | compilations { 67 | val main by getting { 68 | extraOpts("-Xobjc-generics") 69 | } 70 | } 71 | 72 | binaries.framework { 73 | baseName = frameworkName 74 | linkerOpts("-lsqlite3") 75 | } 76 | } 77 | 78 | tasks.register("debugFramework") { 79 | baseName = frameworkName 80 | group = "Universal framework" 81 | description = "Builds a universal debug framework" 82 | 83 | from(iosX64.binaries.getFramework("DEBUG")) 84 | } 85 | 86 | tasks.register("releaseFramework") { 87 | baseName = frameworkName 88 | group = "Universal framework" 89 | description = "Builds a universal release framework" 90 | 91 | from(iosArm64.binaries.getFramework("RELEASE"), iosArm32.binaries.getFramework("RELEASE")) 92 | } 93 | } 94 | 95 | android { 96 | compileSdkVersion(Versions.compileSdkVersion) 97 | buildToolsVersion = Versions.buildToolsVersion 98 | defaultConfig { 99 | minSdkVersion(Versions.minSdkVersion) 100 | targetSdkVersion(Versions.targetSdkVersion) 101 | versionCode = Versions.mobileVersionCode 102 | versionName = Versions.mobileVersionName 103 | } 104 | 105 | sourceSets.forEach { 106 | it.manifest.srcFile("src/androidMain/AndroidManifest.xml") 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /common/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/src/androidMain/kotlin/com/github/aakira/multithreadmpp/common/db/DbActual.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.db 2 | 3 | import android.content.Context 4 | import com.github.aakira.multithreadmpp.db.GreetingDatabase 5 | import com.squareup.sqldelight.android.AndroidSqliteDriver 6 | 7 | // db 8 | lateinit var mppAppContext: Context 9 | 10 | actual fun createDb(): GreetingDatabase? = 11 | GreetingDatabase(AndroidSqliteDriver(GreetingDatabase.Schema, mppAppContext, dbName)) 12 | -------------------------------------------------------------------------------- /common/src/androidMain/kotlin/com/github/aakira/multithreadmpp/common/util/ThreadUtilActual.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.util 2 | 3 | import android.os.Looper 4 | import kotlinx.coroutines.CoroutineDispatcher 5 | import kotlinx.coroutines.Dispatchers 6 | 7 | internal actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO 8 | 9 | internal actual fun isMainThread(): Boolean = Looper.getMainLooper() === Looper.myLooper() 10 | 11 | internal actual fun currentThreadName(): String = Thread.currentThread().name 12 | 13 | actual fun T.freeze(): T = this 14 | -------------------------------------------------------------------------------- /common/src/commonMain/kotlin/com/github/aakira/multithreadmpp/common/GreetingService.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common 2 | 3 | import com.github.aakira.multithreadmpp.common.db.GreetingDao 4 | import com.github.aakira.multithreadmpp.common.model.Greeting 5 | import com.github.aakira.multithreadmpp.common.util.assertNotMainThread 6 | import com.github.aakira.multithreadmpp.common.util.backgroundDispatcher 7 | import com.github.aakira.multithreadmpp.common.util.currentThreadName 8 | import com.github.aakira.multithreadmpp.common.util.doOnNext 9 | import com.squareup.sqldelight.Query 10 | import kotlinx.coroutines.flow.Flow 11 | import kotlinx.coroutines.flow.flowOn 12 | 13 | class GreetingService { 14 | 15 | private val dao = GreetingDao() 16 | 17 | fun saveGreetings(greeting: String) { 18 | dao.storeGreeting(greeting) 19 | } 20 | 21 | fun getGreetings(): Flow> = 22 | dao.getGreetings() 23 | .doOnNext { 24 | assertNotMainThread() 25 | 26 | println("----------------") 27 | println("Common Background Thread: ${currentThreadName()}") 28 | println("----------------") 29 | } 30 | .flowOn(backgroundDispatcher) 31 | } 32 | -------------------------------------------------------------------------------- /common/src/commonMain/kotlin/com/github/aakira/multithreadmpp/common/db/GreetingDao.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.db 2 | 3 | import com.github.aakira.multithreadmpp.common.model.Greeting 4 | import com.github.aakira.multithreadmpp.common.util.freeze 5 | import com.github.aakira.multithreadmpp.db.GreetingDatabase 6 | import com.squareup.sqldelight.Query 7 | import kotlinx.coroutines.channels.Channel 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.flow 10 | import kotlinx.coroutines.flow.flowOf 11 | 12 | expect fun createDb(): GreetingDatabase? 13 | 14 | internal const val dbName: String = "greeting.db" 15 | 16 | class GreetingDao { 17 | 18 | private val greetingDatabase = createDb() 19 | private val queries = greetingDatabase?.greetingQueries 20 | 21 | fun storeGreeting(hello: String) { 22 | queries?.insertItem(hello) 23 | } 24 | 25 | fun getGreetings(): Flow> { 26 | val queries = queries ?: return flowOf() 27 | 28 | return queries 29 | .selectAll(mapper = { _, hello -> Greeting(hello) }) 30 | .asFlow() 31 | } 32 | } 33 | 34 | internal fun Query.asFlow(): Flow> = flow { 35 | emit(this@asFlow) 36 | 37 | val channel = Channel(Channel.CONFLATED).freeze() 38 | val listener = object : Query.Listener { 39 | override fun queryResultsChanged() { 40 | channel.offer(Unit) 41 | } 42 | } 43 | 44 | addListener(listener) 45 | try { 46 | for (item in channel) { 47 | emit(this@asFlow) 48 | } 49 | } finally { 50 | removeListener(listener) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /common/src/commonMain/kotlin/com/github/aakira/multithreadmpp/common/model/Greeting.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.model 2 | 3 | data class Greeting(val hello: String) 4 | -------------------------------------------------------------------------------- /common/src/commonMain/kotlin/com/github/aakira/multithreadmpp/common/util/FlowUtil.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.util 2 | 3 | import kotlinx.coroutines.ExperimentalCoroutinesApi 4 | import kotlinx.coroutines.flow.Flow 5 | import kotlinx.coroutines.flow.transform 6 | 7 | @UseExperimental(ExperimentalCoroutinesApi::class) 8 | inline fun Flow.doOnNext(crossinline block: suspend (T) -> Unit): Flow = 9 | transform { value -> 10 | block(value) 11 | return@transform emit(value) 12 | } 13 | -------------------------------------------------------------------------------- /common/src/commonMain/kotlin/com/github/aakira/multithreadmpp/common/util/ThreadUtil.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.util 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | 5 | internal expect val backgroundDispatcher: CoroutineDispatcher 6 | 7 | internal expect fun isMainThread(): Boolean 8 | 9 | internal expect fun currentThreadName(): String 10 | 11 | internal fun assertNotMainThread() { 12 | if (isMainThread()) 13 | throw IllegalStateException("This is main thread") 14 | } 15 | 16 | expect fun T.freeze(): T 17 | -------------------------------------------------------------------------------- /common/src/commonMain/sqldelight/com/github/aakira/multithreadmpp/db/Greeting.sq: -------------------------------------------------------------------------------- 1 | CREATE TABLE Greeting( 2 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 3 | hello TEXT NOT NULL 4 | ); 5 | 6 | insertItem: 7 | INSERT OR REPLACE INTO Greeting(hello) VALUES(?); 8 | 9 | selectAll: 10 | SELECT * FROM Greeting; 11 | 12 | selectById: 13 | SELECT * FROM Greeting WHERE id = ?; 14 | -------------------------------------------------------------------------------- /common/src/iosMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/src/iosMain/kotlin/com/github/aakira/multithreadmpp/common/GreetingService.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common 2 | 3 | import com.github.aakira.multithreadmpp.common.model.Greeting 4 | import com.github.aakira.multithreadmpp.common.util.currentThreadName 5 | import com.github.aakira.multithreadmpp.common.util.doOnNext 6 | import com.github.aakira.multithreadmpp.common.util.mainScope 7 | import kotlinx.coroutines.ExperimentalCoroutinesApi 8 | import kotlinx.coroutines.flow.catch 9 | import kotlinx.coroutines.flow.launchIn 10 | import kotlinx.coroutines.flow.onEach 11 | 12 | @UseExperimental(ExperimentalCoroutinesApi::class) 13 | fun GreetingService.getGreetings( 14 | successCallback: (Greeting) -> Unit, 15 | errorCallback: (Throwable) -> Unit 16 | ) { 17 | getGreetings() 18 | .doOnNext { 19 | println("iOS Actual Thread: " + currentThreadName()) 20 | } 21 | .onEach { 22 | it.executeAsList() 23 | .firstOrNull() 24 | ?.let(successCallback) 25 | } 26 | .catch { 27 | errorCallback(it) 28 | } 29 | .launchIn(mainScope) 30 | } 31 | -------------------------------------------------------------------------------- /common/src/iosMain/kotlin/com/github/aakira/multithreadmpp/common/db/DbActual.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.db 2 | 3 | import com.github.aakira.multithreadmpp.db.GreetingDatabase 4 | import com.squareup.sqldelight.drivers.ios.NativeSqliteDriver 5 | 6 | actual fun createDb(): GreetingDatabase? = 7 | GreetingDatabase(NativeSqliteDriver(GreetingDatabase.Schema, dbName)) 8 | -------------------------------------------------------------------------------- /common/src/iosMain/kotlin/com/github/aakira/multithreadmpp/common/util/ThreadUtil.kt: -------------------------------------------------------------------------------- 1 | package com.github.aakira.multithreadmpp.common.util 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.CoroutineExceptionHandler 5 | import kotlinx.coroutines.CoroutineScope 6 | import kotlinx.coroutines.Dispatchers 7 | import kotlinx.coroutines.ExperimentalCoroutinesApi 8 | import kotlinx.coroutines.Job 9 | import platform.Foundation.NSThread 10 | import kotlin.coroutines.CoroutineContext 11 | import kotlin.native.concurrent.freeze 12 | 13 | @UseExperimental(ExperimentalCoroutinesApi::class) 14 | internal actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.Default 15 | 16 | internal actual fun isMainThread(): Boolean = NSThread.isMainThread 17 | 18 | internal actual fun currentThreadName(): String = NSThread.currentThread.toString() 19 | 20 | internal val mainScope = ModelScope(Dispatchers.Main) 21 | 22 | internal class ModelScope(private val mainContext: CoroutineContext) : CoroutineScope { 23 | private val job = Job() 24 | private val exceptionHandler = CoroutineExceptionHandler { _, throwable -> 25 | println("Error $throwable") 26 | } 27 | 28 | override val coroutineContext: CoroutineContext 29 | get() = mainContext + job + exceptionHandler 30 | } 31 | 32 | actual fun T.freeze(): T = freeze() 33 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Dec 03 20:44:22 JST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | #distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-milestone-3-all.zip 7 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip 8 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ios/ios.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3DB5FC8923973890007E55E7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DB5FC8823973890007E55E7 /* AppDelegate.swift */; }; 11 | 3DB5FC8B23973890007E55E7 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DB5FC8A23973890007E55E7 /* SceneDelegate.swift */; }; 12 | 3DB5FC8D23973890007E55E7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DB5FC8C23973890007E55E7 /* ViewController.swift */; }; 13 | 3DB5FC9023973890007E55E7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3DB5FC8E23973890007E55E7 /* Main.storyboard */; }; 14 | 3DB5FC9223973892007E55E7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3DB5FC9123973892007E55E7 /* Assets.xcassets */; }; 15 | 3DB5FC9523973892007E55E7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3DB5FC9323973892007E55E7 /* LaunchScreen.storyboard */; }; 16 | 3DED57C22399D5AD00E315B2 /* common.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DED57B92399329200E315B2 /* common.framework */; }; 17 | 3DED57C32399D5AD00E315B2 /* common.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3DED57B92399329200E315B2 /* common.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 3DED57C42399D5AD00E315B2 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | 3DED57C32399D5AD00E315B2 /* common.framework in Embed Frameworks */, 28 | ); 29 | name = "Embed Frameworks"; 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXCopyFilesBuildPhase section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 3DB5FC8523973890007E55E7 /* ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 3DB5FC8823973890007E55E7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 3DB5FC8A23973890007E55E7 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 38 | 3DB5FC8C23973890007E55E7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 39 | 3DB5FC8F23973890007E55E7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 40 | 3DB5FC9123973892007E55E7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 41 | 3DB5FC9423973892007E55E7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 42 | 3DB5FC9623973892007E55E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | 3DB5FC9D2397395D007E55E7 /* common.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = common.framework; path = ../common/build/bin/ios/debugFramework/common.framework; sourceTree = ""; }; 44 | 3DED57B92399329200E315B2 /* common.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = common.framework; path = "../common/build/fat-framework/common.framework"; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 3DB5FC8223973890007E55E7 /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | 3DED57C22399D5AD00E315B2 /* common.framework in Frameworks */, 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | 3DB5FC7C23973890007E55E7 = { 60 | isa = PBXGroup; 61 | children = ( 62 | 3DB5FC8723973890007E55E7 /* ios */, 63 | 3DB5FC8623973890007E55E7 /* Products */, 64 | 3DB5FC9C2397395D007E55E7 /* Frameworks */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 3DB5FC8623973890007E55E7 /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 3DB5FC8523973890007E55E7 /* ios.app */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 3DB5FC8723973890007E55E7 /* ios */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 3DB5FC8823973890007E55E7 /* AppDelegate.swift */, 80 | 3DB5FC8A23973890007E55E7 /* SceneDelegate.swift */, 81 | 3DB5FC8C23973890007E55E7 /* ViewController.swift */, 82 | 3DB5FC8E23973890007E55E7 /* Main.storyboard */, 83 | 3DB5FC9123973892007E55E7 /* Assets.xcassets */, 84 | 3DB5FC9323973892007E55E7 /* LaunchScreen.storyboard */, 85 | 3DB5FC9623973892007E55E7 /* Info.plist */, 86 | ); 87 | path = ios; 88 | sourceTree = ""; 89 | }; 90 | 3DB5FC9C2397395D007E55E7 /* Frameworks */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 3DED57B92399329200E315B2 /* common.framework */, 94 | 3DB5FC9D2397395D007E55E7 /* common.framework */, 95 | ); 96 | name = Frameworks; 97 | sourceTree = ""; 98 | }; 99 | /* End PBXGroup section */ 100 | 101 | /* Begin PBXNativeTarget section */ 102 | 3DB5FC8423973890007E55E7 /* ios */ = { 103 | isa = PBXNativeTarget; 104 | buildConfigurationList = 3DB5FC9923973892007E55E7 /* Build configuration list for PBXNativeTarget "ios" */; 105 | buildPhases = ( 106 | 3DB5FCA12397D09A007E55E7 /* ShellScript */, 107 | 3DB5FC8123973890007E55E7 /* Sources */, 108 | 3DB5FC8223973890007E55E7 /* Frameworks */, 109 | 3DB5FC8323973890007E55E7 /* Resources */, 110 | 3DED57C42399D5AD00E315B2 /* Embed Frameworks */, 111 | ); 112 | buildRules = ( 113 | ); 114 | dependencies = ( 115 | ); 116 | name = ios; 117 | productName = ios; 118 | productReference = 3DB5FC8523973890007E55E7 /* ios.app */; 119 | productType = "com.apple.product-type.application"; 120 | }; 121 | /* End PBXNativeTarget section */ 122 | 123 | /* Begin PBXProject section */ 124 | 3DB5FC7D23973890007E55E7 /* Project object */ = { 125 | isa = PBXProject; 126 | attributes = { 127 | LastSwiftUpdateCheck = 1120; 128 | LastUpgradeCheck = 1120; 129 | ORGANIZATIONNAME = aakira; 130 | TargetAttributes = { 131 | 3DB5FC8423973890007E55E7 = { 132 | CreatedOnToolsVersion = 11.2; 133 | }; 134 | }; 135 | }; 136 | buildConfigurationList = 3DB5FC8023973890007E55E7 /* Build configuration list for PBXProject "ios" */; 137 | compatibilityVersion = "Xcode 9.3"; 138 | developmentRegion = en; 139 | hasScannedForEncodings = 0; 140 | knownRegions = ( 141 | en, 142 | Base, 143 | ); 144 | mainGroup = 3DB5FC7C23973890007E55E7; 145 | productRefGroup = 3DB5FC8623973890007E55E7 /* Products */; 146 | projectDirPath = ""; 147 | projectRoot = ""; 148 | targets = ( 149 | 3DB5FC8423973890007E55E7 /* ios */, 150 | ); 151 | }; 152 | /* End PBXProject section */ 153 | 154 | /* Begin PBXResourcesBuildPhase section */ 155 | 3DB5FC8323973890007E55E7 /* Resources */ = { 156 | isa = PBXResourcesBuildPhase; 157 | buildActionMask = 2147483647; 158 | files = ( 159 | 3DB5FC9523973892007E55E7 /* LaunchScreen.storyboard in Resources */, 160 | 3DB5FC9223973892007E55E7 /* Assets.xcassets in Resources */, 161 | 3DB5FC9023973890007E55E7 /* Main.storyboard in Resources */, 162 | ); 163 | runOnlyForDeploymentPostprocessing = 0; 164 | }; 165 | /* End PBXResourcesBuildPhase section */ 166 | 167 | /* Begin PBXShellScriptBuildPhase section */ 168 | 3DB5FCA12397D09A007E55E7 /* ShellScript */ = { 169 | isa = PBXShellScriptBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | ); 173 | inputFileListPaths = ( 174 | ); 175 | inputPaths = ( 176 | ); 177 | outputFileListPaths = ( 178 | ); 179 | outputPaths = ( 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | shellPath = /bin/sh; 183 | shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd \"$SRCROOT/../\"\n./gradlew debugFramework\n"; 184 | }; 185 | /* End PBXShellScriptBuildPhase section */ 186 | 187 | /* Begin PBXSourcesBuildPhase section */ 188 | 3DB5FC8123973890007E55E7 /* Sources */ = { 189 | isa = PBXSourcesBuildPhase; 190 | buildActionMask = 2147483647; 191 | files = ( 192 | 3DB5FC8D23973890007E55E7 /* ViewController.swift in Sources */, 193 | 3DB5FC8923973890007E55E7 /* AppDelegate.swift in Sources */, 194 | 3DB5FC8B23973890007E55E7 /* SceneDelegate.swift in Sources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXSourcesBuildPhase section */ 199 | 200 | /* Begin PBXVariantGroup section */ 201 | 3DB5FC8E23973890007E55E7 /* Main.storyboard */ = { 202 | isa = PBXVariantGroup; 203 | children = ( 204 | 3DB5FC8F23973890007E55E7 /* Base */, 205 | ); 206 | name = Main.storyboard; 207 | sourceTree = ""; 208 | }; 209 | 3DB5FC9323973892007E55E7 /* LaunchScreen.storyboard */ = { 210 | isa = PBXVariantGroup; 211 | children = ( 212 | 3DB5FC9423973892007E55E7 /* Base */, 213 | ); 214 | name = LaunchScreen.storyboard; 215 | sourceTree = ""; 216 | }; 217 | /* End PBXVariantGroup section */ 218 | 219 | /* Begin XCBuildConfiguration section */ 220 | 3DB5FC9723973892007E55E7 /* Debug */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | ALWAYS_SEARCH_USER_PATHS = NO; 224 | CLANG_ANALYZER_NONNULL = YES; 225 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 226 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 227 | CLANG_CXX_LIBRARY = "libc++"; 228 | CLANG_ENABLE_MODULES = YES; 229 | CLANG_ENABLE_OBJC_ARC = YES; 230 | CLANG_ENABLE_OBJC_WEAK = YES; 231 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 232 | CLANG_WARN_BOOL_CONVERSION = YES; 233 | CLANG_WARN_COMMA = YES; 234 | CLANG_WARN_CONSTANT_CONVERSION = YES; 235 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 236 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 237 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 238 | CLANG_WARN_EMPTY_BODY = YES; 239 | CLANG_WARN_ENUM_CONVERSION = YES; 240 | CLANG_WARN_INFINITE_RECURSION = YES; 241 | CLANG_WARN_INT_CONVERSION = YES; 242 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 243 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 244 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 245 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 246 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 247 | CLANG_WARN_STRICT_PROTOTYPES = YES; 248 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 249 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 250 | CLANG_WARN_UNREACHABLE_CODE = YES; 251 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 252 | COPY_PHASE_STRIP = NO; 253 | DEBUG_INFORMATION_FORMAT = dwarf; 254 | ENABLE_BITCODE = NO; 255 | ENABLE_STRICT_OBJC_MSGSEND = YES; 256 | ENABLE_TESTABILITY = YES; 257 | FRAMEWORK_SEARCH_PATHS = "$SRCROOT/../common/build/fat-framework/common.framework"; 258 | GCC_C_LANGUAGE_STANDARD = gnu11; 259 | GCC_DYNAMIC_NO_PIC = NO; 260 | GCC_NO_COMMON_BLOCKS = YES; 261 | GCC_OPTIMIZATION_LEVEL = 0; 262 | GCC_PREPROCESSOR_DEFINITIONS = ( 263 | "DEBUG=1", 264 | "$(inherited)", 265 | ); 266 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 267 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 268 | GCC_WARN_UNDECLARED_SELECTOR = YES; 269 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 270 | GCC_WARN_UNUSED_FUNCTION = YES; 271 | GCC_WARN_UNUSED_VARIABLE = YES; 272 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 273 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 274 | MTL_FAST_MATH = YES; 275 | ONLY_ACTIVE_ARCH = YES; 276 | SDKROOT = iphoneos; 277 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 278 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 279 | }; 280 | name = Debug; 281 | }; 282 | 3DB5FC9823973892007E55E7 /* Release */ = { 283 | isa = XCBuildConfiguration; 284 | buildSettings = { 285 | ALWAYS_SEARCH_USER_PATHS = NO; 286 | CLANG_ANALYZER_NONNULL = YES; 287 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 288 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 289 | CLANG_CXX_LIBRARY = "libc++"; 290 | CLANG_ENABLE_MODULES = YES; 291 | CLANG_ENABLE_OBJC_ARC = YES; 292 | CLANG_ENABLE_OBJC_WEAK = YES; 293 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 294 | CLANG_WARN_BOOL_CONVERSION = YES; 295 | CLANG_WARN_COMMA = YES; 296 | CLANG_WARN_CONSTANT_CONVERSION = YES; 297 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 298 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 299 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 300 | CLANG_WARN_EMPTY_BODY = YES; 301 | CLANG_WARN_ENUM_CONVERSION = YES; 302 | CLANG_WARN_INFINITE_RECURSION = YES; 303 | CLANG_WARN_INT_CONVERSION = YES; 304 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 305 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 306 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 307 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 308 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 309 | CLANG_WARN_STRICT_PROTOTYPES = YES; 310 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 311 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 312 | CLANG_WARN_UNREACHABLE_CODE = YES; 313 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 314 | COPY_PHASE_STRIP = NO; 315 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 316 | ENABLE_BITCODE = NO; 317 | ENABLE_NS_ASSERTIONS = NO; 318 | ENABLE_STRICT_OBJC_MSGSEND = YES; 319 | FRAMEWORK_SEARCH_PATHS = "$SRCROOT/../common/build/fat-framework/common.framework"; 320 | GCC_C_LANGUAGE_STANDARD = gnu11; 321 | GCC_NO_COMMON_BLOCKS = YES; 322 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 323 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 324 | GCC_WARN_UNDECLARED_SELECTOR = YES; 325 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 326 | GCC_WARN_UNUSED_FUNCTION = YES; 327 | GCC_WARN_UNUSED_VARIABLE = YES; 328 | IPHONEOS_DEPLOYMENT_TARGET = 13.2; 329 | MTL_ENABLE_DEBUG_INFO = NO; 330 | MTL_FAST_MATH = YES; 331 | SDKROOT = iphoneos; 332 | SWIFT_COMPILATION_MODE = wholemodule; 333 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 334 | VALIDATE_PRODUCT = YES; 335 | }; 336 | name = Release; 337 | }; 338 | 3DB5FC9A23973892007E55E7 /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 342 | CODE_SIGN_STYLE = Automatic; 343 | FRAMEWORK_SEARCH_PATHS = "$SRCROOT/../common/build/fat-framework/"; 344 | INFOPLIST_FILE = ios/Info.plist; 345 | LD_RUNPATH_SEARCH_PATHS = ( 346 | "$(inherited)", 347 | "@executable_path/Frameworks", 348 | ); 349 | PRODUCT_BUNDLE_IDENTIFIER = com.github.aakira.ios; 350 | PRODUCT_NAME = "$(TARGET_NAME)"; 351 | SWIFT_VERSION = 5.0; 352 | TARGETED_DEVICE_FAMILY = "1,2"; 353 | }; 354 | name = Debug; 355 | }; 356 | 3DB5FC9B23973892007E55E7 /* Release */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CODE_SIGN_STYLE = Automatic; 361 | FRAMEWORK_SEARCH_PATHS = "$SRCROOT/../common/build/fat-framework/"; 362 | INFOPLIST_FILE = ios/Info.plist; 363 | LD_RUNPATH_SEARCH_PATHS = ( 364 | "$(inherited)", 365 | "@executable_path/Frameworks", 366 | ); 367 | PRODUCT_BUNDLE_IDENTIFIER = com.github.aakira.ios; 368 | PRODUCT_NAME = "$(TARGET_NAME)"; 369 | SWIFT_VERSION = 5.0; 370 | TARGETED_DEVICE_FAMILY = "1,2"; 371 | }; 372 | name = Release; 373 | }; 374 | /* End XCBuildConfiguration section */ 375 | 376 | /* Begin XCConfigurationList section */ 377 | 3DB5FC8023973890007E55E7 /* Build configuration list for PBXProject "ios" */ = { 378 | isa = XCConfigurationList; 379 | buildConfigurations = ( 380 | 3DB5FC9723973892007E55E7 /* Debug */, 381 | 3DB5FC9823973892007E55E7 /* Release */, 382 | ); 383 | defaultConfigurationIsVisible = 0; 384 | defaultConfigurationName = Release; 385 | }; 386 | 3DB5FC9923973892007E55E7 /* Build configuration list for PBXNativeTarget "ios" */ = { 387 | isa = XCConfigurationList; 388 | buildConfigurations = ( 389 | 3DB5FC9A23973892007E55E7 /* Debug */, 390 | 3DB5FC9B23973892007E55E7 /* Release */, 391 | ); 392 | defaultConfigurationIsVisible = 0; 393 | defaultConfigurationName = Release; 394 | }; 395 | /* End XCConfigurationList section */ 396 | }; 397 | rootObject = 3DB5FC7D23973890007E55E7 /* Project object */; 398 | } 399 | -------------------------------------------------------------------------------- /ios/ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/ios.xcodeproj/project.xcworkspace/xcuserdata/aakira.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AAkira/multithread-mpp/f294c6e45b6f6f67f7a4c01cc1db03d2e6938167/ios/ios.xcodeproj/project.xcworkspace/xcuserdata/aakira.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ios/ios.xcodeproj/xcuserdata/aakira.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /ios/ios.xcodeproj/xcuserdata/aakira.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ios.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ios/ios/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | 6 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 7 | // Override point for customization after application launch. 8 | return true 9 | } 10 | 11 | // MARK: UISceneSession Lifecycle 12 | 13 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 14 | // Called when a new scene session is being created. 15 | // Use this method to select a configuration to create the new scene with. 16 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 17 | } 18 | 19 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 20 | // Called when the user discards a scene session. 21 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 22 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /ios/ios/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /ios/ios/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ios/ios/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ios/ios/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/ios/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSAppTransportSecurity 6 | 7 | NSAllowsArbitraryLoads 8 | 9 | 10 | CFBundleDevelopmentRegion 11 | $(DEVELOPMENT_LANGUAGE) 12 | CFBundleExecutable 13 | $(EXECUTABLE_NAME) 14 | CFBundleIdentifier 15 | $(PRODUCT_BUNDLE_IDENTIFIER) 16 | CFBundleInfoDictionaryVersion 17 | 6.0 18 | CFBundleName 19 | $(PRODUCT_NAME) 20 | CFBundlePackageType 21 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 22 | CFBundleShortVersionString 23 | 1.0 24 | CFBundleVersion 25 | 1 26 | LSRequiresIPhoneOS 27 | 28 | UIApplicationSceneManifest 29 | 30 | UIApplicationSupportsMultipleScenes 31 | 32 | UISceneConfigurations 33 | 34 | UIWindowSceneSessionRoleApplication 35 | 36 | 37 | UISceneConfigurationName 38 | Default Configuration 39 | UISceneDelegateClassName 40 | $(PRODUCT_MODULE_NAME).SceneDelegate 41 | UISceneStoryboardFile 42 | Main 43 | 44 | 45 | 46 | 47 | UILaunchStoryboardName 48 | LaunchScreen 49 | UIMainStoryboardFile 50 | Main 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | UISupportedInterfaceOrientations~ipad 62 | 63 | UIInterfaceOrientationPortrait 64 | UIInterfaceOrientationPortraitUpsideDown 65 | UIInterfaceOrientationLandscapeLeft 66 | UIInterfaceOrientationLandscapeRight 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /ios/ios/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 4 | 5 | var window: UIWindow? 6 | 7 | 8 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 9 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 10 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 11 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 12 | guard let _ = (scene as? UIWindowScene) else { return } 13 | } 14 | 15 | func sceneDidDisconnect(_ scene: UIScene) { 16 | // Called as the scene is being released by the system. 17 | // This occurs shortly after the scene enters the background, or when its session is discarded. 18 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 19 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 20 | } 21 | 22 | func sceneDidBecomeActive(_ scene: UIScene) { 23 | // Called when the scene has moved from an inactive state to an active state. 24 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 25 | } 26 | 27 | func sceneWillResignActive(_ scene: UIScene) { 28 | // Called when the scene will move from an active state to an inactive state. 29 | // This may occur due to temporary interruptions (ex. an incoming phone call). 30 | } 31 | 32 | func sceneWillEnterForeground(_ scene: UIScene) { 33 | // Called as the scene transitions from the background to the foreground. 34 | // Use this method to undo the changes made on entering the background. 35 | } 36 | 37 | func sceneDidEnterBackground(_ scene: UIScene) { 38 | // Called as the scene transitions from the foreground to the background. 39 | // Use this method to save data, release shared resources, and store enough scene-specific state information 40 | // to restore the scene back to its current state. 41 | } 42 | 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /ios/ios/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import common 3 | 4 | class ViewController: UIViewController { 5 | override func viewDidLoad() { 6 | super.viewDidLoad() 7 | let label = UILabel(frame: 8 | CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height) 9 | ) 10 | label.textAlignment = .center 11 | label.font = label.font.withSize(26) 12 | self.view.addSubview(label) 13 | 14 | let service = GreetingService() 15 | service.saveGreetings(greeting: "Hello") 16 | service.getGreetings ( 17 | successCallback: { result in 18 | label.text = result.hello 19 | }, errorCallback: { error in 20 | label.text = error.message 21 | print(error) 22 | } 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "MultithreadMpp" 2 | 3 | include(":common", ":android") 4 | --------------------------------------------------------------------------------