├── .github └── workflows │ └── android.yml ├── .gitignore ├── AppServicesUsageSamples ├── .gitignore ├── README.md ├── Screenshots │ ├── dynamic-data-browser.png │ ├── import-app-console-example.png │ └── screenshot-appservices.png ├── apps │ ├── dynamic-data │ │ ├── .mdb │ │ │ └── meta.json │ │ ├── README.md │ │ ├── auth │ │ │ ├── custom_user_data.json │ │ │ └── providers.json │ │ ├── data_sources │ │ │ └── mongodb-atlas │ │ │ │ ├── config.json │ │ │ │ ├── default_rule.json │ │ │ │ └── dynamic_data │ │ │ │ └── DynamicDataEntity │ │ │ │ └── schema.json │ │ ├── environments │ │ │ ├── development.json │ │ │ ├── no-environment.json │ │ │ ├── production.json │ │ │ ├── qa.json │ │ │ └── testing.json │ │ ├── functions │ │ │ └── config.json │ │ ├── graphql │ │ │ ├── config.json │ │ │ └── validation_settings.json │ │ ├── hosting │ │ │ └── config.json │ │ ├── https_endpoints │ │ │ └── config.json │ │ ├── root_config.json │ │ └── sync │ │ │ └── config.json │ ├── error-handling │ │ ├── README.md │ │ ├── auth │ │ │ ├── custom_user_data.json │ │ │ └── providers.json │ │ ├── compensating-write.png │ │ ├── data_sources │ │ │ └── mongodb-atlas │ │ │ │ ├── config.json │ │ │ │ ├── default_rule.json │ │ │ │ └── error-handling │ │ │ │ └── Entry │ │ │ │ ├── relationships.json │ │ │ │ └── schema.json │ │ ├── environments │ │ │ ├── development.json │ │ │ ├── no-environment.json │ │ │ ├── production.json │ │ │ ├── qa.json │ │ │ └── testing.json │ │ ├── functions │ │ │ ├── config.json │ │ │ └── triggerClientReset.js │ │ ├── graphql │ │ │ └── config.json │ │ ├── http_endpoints │ │ │ └── config.json │ │ ├── realm_config.json │ │ ├── step1.png │ │ ├── step2.png │ │ ├── step3.png │ │ ├── step4.png │ │ └── sync │ │ │ └── config.json │ ├── presence-detection │ │ ├── README.md │ │ ├── auth │ │ │ ├── custom_user_data.json │ │ │ └── providers.json │ │ ├── data_sources │ │ │ └── mongodb-atlas │ │ │ │ ├── config.json │ │ │ │ ├── default_rule.json │ │ │ │ └── presence-detection │ │ │ │ └── user_status │ │ │ │ ├── relationships.json │ │ │ │ └── schema.json │ │ ├── environments │ │ │ ├── development.json │ │ │ ├── no-environment.json │ │ │ ├── production.json │ │ │ ├── qa.json │ │ │ └── testing.json │ │ ├── functions │ │ │ ├── config.json │ │ │ └── logPresenceDetector.js │ │ ├── graphql │ │ │ └── config.json │ │ ├── http_endpoints │ │ │ └── config.json │ │ ├── log_forwarders │ │ │ └── presenceDetector.json │ │ ├── logs.png │ │ ├── presence-flow.svg │ │ ├── realm_config.json │ │ └── sync │ │ │ └── config.json │ └── property-encryption │ │ ├── README.md │ │ ├── auth │ │ ├── custom_user_data.json │ │ └── providers.json │ │ ├── data_sources │ │ └── mongodb-atlas │ │ │ ├── config.json │ │ │ ├── default_rule.json │ │ │ └── field_encryption │ │ │ ├── custom_data │ │ │ ├── relationships.json │ │ │ └── schema.json │ │ │ └── secret_record │ │ │ ├── relationships.json │ │ │ └── schema.json │ │ ├── diagram1.svg │ │ ├── diagram2.svg │ │ ├── diagram3.svg │ │ ├── environments │ │ ├── development.json │ │ ├── no-environment.json │ │ ├── production.json │ │ ├── qa.json │ │ └── testing.json │ │ ├── functions │ │ ├── config.json │ │ ├── initializeCustomData.js │ │ └── updateKeyStore.js │ │ ├── graphql │ │ └── config.json │ │ ├── http_endpoints │ │ └── config.json │ │ ├── realm_config.json │ │ └── sync │ │ └── config.json ├── build.gradle.kts ├── demo │ ├── .gitignore │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── io │ │ │ └── realm │ │ │ └── curatedsyncexamples │ │ │ └── KeyHelperTests.kt │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── certificate.crt │ │ ├── java │ │ └── io │ │ │ └── realm │ │ │ └── appservicesusagesamples │ │ │ ├── AppServicesUsageSamplesApp.kt │ │ │ ├── Constants.kt │ │ │ ├── DependencyInjection.kt │ │ │ ├── SampleSelectorActivity.kt │ │ │ ├── dynamicdata │ │ │ ├── DependencyInjection.kt │ │ │ ├── DynamicDataActivity.kt │ │ │ ├── models │ │ │ │ └── DynamicDataEntity.kt │ │ │ └── ui │ │ │ │ ├── DynamicDataScreen.kt │ │ │ │ └── DynamicDataViewModel.kt │ │ │ ├── errorhandling │ │ │ ├── DependencyInjection.kt │ │ │ ├── ErrorHandlingActivity.kt │ │ │ ├── models │ │ │ │ └── Entry.kt │ │ │ ├── strategies │ │ │ │ ├── AutomaticUnsyncedDataRecovery.kt │ │ │ │ ├── BackupRealm.kt │ │ │ │ ├── DiscardUnsyncedData.kt │ │ │ │ └── ManualUnsyncedDataRecovery.kt │ │ │ └── ui │ │ │ │ ├── ErrorHandlingScreen.kt │ │ │ │ └── ErrorHandlingViewModel.kt │ │ │ ├── presence │ │ │ ├── DependencyInjection.kt │ │ │ ├── PresenceDetectionActivity.kt │ │ │ ├── models │ │ │ │ └── UserStatus.kt │ │ │ └── ui │ │ │ │ ├── UserStatusListScreen.kt │ │ │ │ └── UserStatusListViewModel.kt │ │ │ ├── propertyencryption │ │ │ ├── DependencyInjection.kt │ │ │ ├── PropertyEncryptionActivity.kt │ │ │ ├── ext │ │ │ │ ├── EncryptionExt.kt │ │ │ │ └── UserExt.kt │ │ │ ├── models │ │ │ │ ├── CustomData.kt │ │ │ │ ├── PropertyEncryptionConfiguration.kt │ │ │ │ ├── SecretRecord.kt │ │ │ │ ├── SecureStringDelegate.kt │ │ │ │ └── SerializableCipherSpec.kt │ │ │ └── ui │ │ │ │ ├── NavGraph.kt │ │ │ │ ├── keystore │ │ │ │ ├── UnlockRemoteKeyStoreScreen.kt │ │ │ │ └── UnlockRemoteKeyStoreViewModel.kt │ │ │ │ ├── login │ │ │ │ ├── LoginScreen.kt │ │ │ │ └── LoginViewModel.kt │ │ │ │ └── records │ │ │ │ ├── SecretRecordsScreen.kt │ │ │ │ └── SecretRecordsViewModel.kt │ │ │ └── ui │ │ │ ├── DemoSelectors.kt │ │ │ ├── SampleSelectorScreen.kt │ │ │ ├── SampleSelectorViewModel.kt │ │ │ └── theme │ │ │ ├── Color.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── baseline_cancel_24.xml │ │ ├── baseline_check_circle_24.xml │ │ ├── ic_launcher_background.xml │ │ └── realmio_logo_vector.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ └── data_extraction_rules.xml ├── gradle.properties ├── gradle │ ├── libs.versions.toml │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts ├── Bookshelf ├── .gitignore ├── README.md ├── Screenshots │ ├── Android │ │ ├── About.png │ │ ├── Results.png │ │ ├── Saved.png │ │ └── Search.png │ └── iOS │ │ ├── About.png │ │ ├── Saved.png │ │ ├── SavedBooks.png │ │ ├── Search.png │ │ └── Search_Pending.png ├── androidApp │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── io │ │ │ └── realm │ │ │ └── sample │ │ │ └── bookshelf │ │ │ └── android │ │ │ ├── MainActivity.kt │ │ │ ├── theme │ │ │ ├── Color.kt │ │ │ ├── Shape.kt │ │ │ ├── Size.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ │ │ └── ui │ │ │ ├── AboutScreen.kt │ │ │ ├── BookshelfViewModel.kt │ │ │ ├── DetailsScreen.kt │ │ │ ├── NavigationScreen.kt │ │ │ ├── SavedBooksScreen.kt │ │ │ └── SearchScreen.kt │ │ └── res │ │ ├── font │ │ ├── eczar_regular.ttf │ │ ├── eczar_semibold.ttf │ │ ├── robotocondensed_bold.ttf │ │ ├── robotocondensed_light.ttf │ │ └── robotocondensed_regular.ttf │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle.kts ├── debug.keystore ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iosApp │ ├── Podfile │ ├── Podfile.lock │ ├── Pods │ │ ├── Local Podspecs │ │ │ └── shared.podspec.json │ │ ├── Manifest.lock │ │ ├── Pods.xcodeproj │ │ │ └── project.pbxproj │ │ └── Target Support Files │ │ │ ├── Pods-iosApp │ │ │ ├── Pods-iosApp-Info.plist │ │ │ ├── Pods-iosApp-acknowledgements.markdown │ │ │ ├── Pods-iosApp-acknowledgements.plist │ │ │ ├── Pods-iosApp-dummy.m │ │ │ ├── Pods-iosApp-umbrella.h │ │ │ ├── Pods-iosApp.debug.xcconfig │ │ │ └── Pods-iosApp.release.xcconfig │ │ │ └── shared │ │ │ ├── shared.debug.xcconfig │ │ │ └── shared.release.xcconfig │ ├── iosApp.xcodeproj │ │ └── project.pbxproj │ ├── iosApp.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── iosApp │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ │ └── iOSApp.swift ├── settings.gradle.kts └── shared │ ├── build.gradle.kts │ ├── shared.podspec │ └── src │ ├── androidMain │ └── AndroidManifest.xml │ └── commonMain │ └── kotlin │ └── io │ └── realm │ └── sample │ └── bookshelf │ ├── BookshelfRepository.kt │ ├── database │ ├── FlowUtils.kt │ └── RealmDatabase.kt │ ├── model │ └── Book.kt │ └── network │ ├── ApiBook.kt │ ├── OpenLibraryApi.kt │ └── SearchResult.kt ├── Intro ├── LICENSE ├── README.md ├── Screenshots │ ├── Android │ │ └── Home.png │ └── iOS │ │ └── Home.png ├── androidApp │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── io │ │ │ └── realm │ │ │ └── example │ │ │ └── kmmsample │ │ │ └── androidApp │ │ │ └── MainActivity.kt │ │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ └── values │ │ ├── colors.xml │ │ └── themes.xml ├── build.gradle.kts ├── debug.keystore ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iosApp │ ├── iosApp.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── iosApp │ │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ │ └── iOSApp.swift ├── settings.gradle.kts └── shared │ ├── build.gradle.kts │ └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ └── io │ │ └── realm │ │ └── example │ │ └── kmmsample │ │ └── Platform.kt │ ├── androidTest │ └── kotlin │ │ └── io │ │ └── realm │ │ └── example │ │ └── kmmsample │ │ └── GreetingTestAndroid.kt │ ├── commonMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── example │ │ └── kmmsample │ │ ├── Calculator.kt │ │ ├── Expression.kt │ │ ├── ExpressionRepository.kt │ │ ├── FlowUtils.kt │ │ ├── Greeting.kt │ │ └── Platform.kt │ ├── commonTest │ └── kotlin │ │ └── io │ │ └── realm │ │ └── example │ │ └── kmmsample │ │ ├── CalculatorTest.kt │ │ └── ExpressionRepositoryTest.kt │ ├── iosMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── example │ │ └── kmmsample │ │ └── Platform.kt │ └── iosTest │ └── kotlin │ └── io │ └── realm │ └── example │ └── kmmsample │ └── GreetingTestIos.kt ├── JVMConsole ├── README.md ├── Screenshots │ ├── Console.png │ ├── DemoConsoleJVM.gif │ └── run.png ├── build.gradle.kts ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ └── io │ └── realm │ └── example │ └── main.kt ├── JavaKotlinMavenInterop ├── README.md ├── Screenshots │ └── java-kotlin-maven-interop.png ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── java-app-gradle │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── mongodb │ │ └── devicesync │ │ └── javainterop │ │ └── gradle │ │ └── JavaGradleApp.java ├── java-app-maven │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── mongodb │ │ └── devicesync │ │ └── javainterop │ │ └── maven │ │ └── JavaMavenApp.java ├── kotlin-lib │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── mongodb │ │ └── devicesync │ │ └── kotlin │ │ ├── RealmRepository.kt │ │ └── Schema.kt └── settings.gradle.kts ├── MultiplatformDemo ├── .gitignore ├── README.md ├── Screenshots │ ├── Android.png │ ├── JVM.png │ ├── Overview.png │ ├── iOS.png │ └── macOS.png ├── androidApp │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── io │ │ │ └── realm │ │ │ └── kotlin │ │ │ └── demo │ │ │ ├── theme │ │ │ ├── Color.kt │ │ │ ├── RealmColor.kt │ │ │ ├── Shape.kt │ │ │ ├── Size.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ │ │ └── ui │ │ │ └── counter │ │ │ ├── AndroidCounterViewModel.kt │ │ │ └── CounterActivity.kt │ │ └── res │ │ └── values │ │ ├── colors.xml │ │ └── styles.xml ├── build.gradle.kts ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iosApp │ ├── Podfile │ ├── Podfile.lock │ ├── iosApp.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── iosApp.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── iosApp │ │ ├── Assets.xcassets │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Theme.swift │ │ ├── ViewModel.swift │ │ └── iOSApp.swift │ ├── iosAppTests │ │ ├── Info.plist │ │ └── iosAppTests.swift │ └── iosAppUITests │ │ ├── Info.plist │ │ └── iosAppUITests.swift ├── jvmApp │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ ├── Main.kt │ │ └── theme │ │ └── RealmColor.kt ├── macosApp │ ├── Podfile │ ├── Podfile.lock │ ├── macosApp.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── macosApp.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── macosApp │ │ ├── Assets.xcassets │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── MacOSApp.swift │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Theme.swift │ │ ├── ViewModel.swift │ │ └── macosApp.entitlements │ ├── macosAppTests │ │ ├── Info.plist │ │ └── macosAppTests.swift │ └── macosAppUITests │ │ ├── Info.plist │ │ └── macosAppUITests.swift ├── settings.gradle.kts └── shared │ ├── build.gradle.kts │ ├── shared.podspec │ └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ └── ui │ │ └── counter │ │ └── Platform.kt │ ├── commonMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ ├── model │ │ ├── CounterRepository.kt │ │ └── entity │ │ │ └── Counter.kt │ │ ├── ui │ │ ├── SharedViewModel.kt │ │ └── counter │ │ │ ├── CounterViewModel.kt │ │ │ ├── Platform.kt │ │ │ └── SharedCounterViewModel.kt │ │ └── util │ │ ├── Closeable.kt │ │ └── FlowUtil.kt │ ├── iosMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ └── ui │ │ └── counter │ │ └── Platform.kt │ ├── jvmMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ └── ui │ │ └── counter │ │ └── Platform.kt │ └── macosMain │ └── kotlin │ └── io │ └── realm │ └── kotlin │ └── demo │ └── ui │ └── counter │ └── Platform.kt ├── MultiplatformDemoWithSync ├── .gitignore ├── README.md ├── Screenshots │ └── kotlin-sync-demo.gif ├── androidApp │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── io │ │ │ └── realm │ │ │ └── kotlin │ │ │ └── demo │ │ │ ├── theme │ │ │ ├── Color.kt │ │ │ ├── RealmColor.kt │ │ │ ├── Shape.kt │ │ │ ├── Size.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ │ │ └── ui │ │ │ └── counter │ │ │ ├── AndroidCounterViewModel.kt │ │ │ └── CounterActivity.kt │ │ └── res │ │ ├── drawable │ │ ├── wifi.xml │ │ └── wifi_off.xml │ │ └── values │ │ ├── colors.xml │ │ └── styles.xml ├── build.gradle.kts ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iosApp │ ├── Podfile │ ├── Podfile.lock │ ├── iosApp.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── iosApp.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── iosApp │ │ ├── Assets.xcassets │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── wifi.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Image.png │ │ │ └── wifi_off.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── ic_wifi_off_black_48dp.png │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Theme.swift │ │ ├── ViewModel.swift │ │ └── iOSApp.swift │ ├── iosAppTests │ │ ├── Info.plist │ │ └── iosAppTests.swift │ └── iosAppUITests │ │ ├── Info.plist │ │ └── iosAppUITests.swift ├── jvmApp │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── kotlin │ │ └── io │ │ │ └── realm │ │ │ └── kotlin │ │ │ └── demo │ │ │ ├── Main.kt │ │ │ └── theme │ │ │ └── RealmColor.kt │ │ └── resources │ │ ├── wifi.xml │ │ └── wifi_off.xml ├── macosApp │ ├── Podfile │ ├── Podfile.lock │ ├── macosApp.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── macosApp.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── macosApp │ │ ├── Assets.xcassets │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── wifi_off.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── ic_wifi_off_black_48dp.png │ │ │ └── wifi_on.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── ic_wifi_black_48dp.png │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── MacOSApp.swift │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Theme.swift │ │ ├── ViewModel.swift │ │ └── macosApp.entitlements │ ├── macosAppTests │ │ ├── Info.plist │ │ └── macosAppTests.swift │ └── macosAppUITests │ │ ├── Info.plist │ │ └── macosAppUITests.swift ├── settings.gradle.kts └── shared │ ├── build.gradle.kts │ ├── shared.podspec │ └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ └── ui │ │ └── counter │ │ └── Platform.kt │ ├── commonMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ ├── model │ │ ├── CounterRepository.kt │ │ └── entity │ │ │ └── Counter.kt │ │ ├── ui │ │ ├── SharedViewModel.kt │ │ └── counter │ │ │ ├── CounterViewModel.kt │ │ │ ├── Platform.kt │ │ │ └── SharedCounterViewModel.kt │ │ └── util │ │ ├── Closeable.kt │ │ ├── Constants.kt │ │ └── FlowUtil.kt │ ├── iosMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ └── ui │ │ └── counter │ │ └── Platform.kt │ ├── jvmMain │ └── kotlin │ │ └── io │ │ └── realm │ │ └── kotlin │ │ └── demo │ │ └── ui │ │ └── counter │ │ └── Platform.kt │ └── macosMain │ └── kotlin │ └── io │ └── realm │ └── kotlin │ └── demo │ └── ui │ └── counter │ └── Platform.kt ├── README.md └── versions └── current.toml /AppServicesUsageSamples/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | local.properties 11 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/Screenshots/dynamic-data-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/Screenshots/dynamic-data-browser.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/Screenshots/import-app-console-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/Screenshots/import-app-console-example.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/Screenshots/screenshot-appservices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/Screenshots/screenshot-appservices.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/.mdb/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "config_version": 20230101, 3 | "app_id": "6655920fc1ed444018db297b", 4 | "group_id": "64c37d22e47344686a325451", 5 | "client_app_id": "dynamic-data-fmzmcph", 6 | "last_pulled": 1717066261 7 | } 8 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/README.md: -------------------------------------------------------------------------------- 1 | # Dynamic data 2 | 3 | With the newly added ability to store collections in mixed properties, you can now store and synchronized 4 | data without pre-known schema. 5 | 6 | This app just holds a single data class that mixes strictly typed properties and a single mixed property 7 | that will be used as an entry point for the potentially deeply nested, dynamic data. 8 | 9 | The Kotlin UI shows each entity and associated 'configuration' mixed property in a tree view. There is 10 | currently no update options in the UI, so data has to be added through the Atlas UI in the 11 | "Data Service" section: 12 | 13 | ![alt text](../../Screenshots/dynamic-data-browser.png "Atlas collection browser") 14 | 15 | Updates will be reflected in the Kotlin UI. 16 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/auth/custom_user_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/auth/providers.json: -------------------------------------------------------------------------------- 1 | { 2 | "anon-user": { 3 | "name": "anon-user", 4 | "type": "anon-user", 5 | "disabled": false 6 | }, 7 | "api-key": { 8 | "name": "api-key", 9 | "type": "api-key", 10 | "disabled": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/data_sources/mongodb-atlas/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongodb-atlas", 3 | "type": "mongodb-atlas", 4 | "config": { 5 | "clusterName": "Cluster0", 6 | "readPreference": "primary", 7 | "wireProtocolEnabled": false 8 | }, 9 | "version": 1 10 | } 11 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/data_sources/mongodb-atlas/default_rule.json: -------------------------------------------------------------------------------- 1 | { 2 | "roles": [ 3 | { 4 | "name": "readAndWriteAll", 5 | "apply_when": {}, 6 | "document_filters": { 7 | "read": true, 8 | "write": true 9 | }, 10 | "insert": true, 11 | "delete": true, 12 | "search": true, 13 | "read": true, 14 | "write": true 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/data_sources/mongodb-atlas/dynamic_data/DynamicDataEntity/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "DynamicDataEntity", 3 | "type": "object", 4 | "required": [ 5 | "_id", 6 | "name" 7 | ], 8 | "properties": { 9 | "_id": { 10 | "bsonType": "objectId" 11 | }, 12 | "configuration": { 13 | "bsonType": "mixed" 14 | }, 15 | "name": { 16 | "bsonType": "string" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/environments/development.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/environments/no-environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/environments/production.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/environments/qa.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/environments/testing.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/functions/config.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/graphql/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "use_natural_pluralization": true, 3 | "disable_schema_introspection": false 4 | } 5 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/graphql/validation_settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "read_validation_action": "ERROR", 3 | "read_validation_level": "STRICT", 4 | "write_validation_action": "ERROR", 5 | "write_validation_level": "STRICT" 6 | } 7 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/hosting/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/https_endpoints/config.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/root_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dynamic-data", 3 | "provider_region": "aws-eu-central-1", 4 | "deployment_model": "LOCAL" 5 | } 6 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/dynamic-data/sync/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "flexible", 3 | "state": "enabled", 4 | "development_mode_enabled": true, 5 | "service_name": "mongodb-atlas", 6 | "database_name": "dynamic_data", 7 | "client_max_offline_days": 30, 8 | "is_recovery_mode_disabled": false 9 | } 10 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/auth/custom_user_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/auth/providers.json: -------------------------------------------------------------------------------- 1 | { 2 | "anon-user": { 3 | "name": "anon-user", 4 | "type": "anon-user", 5 | "disabled": false 6 | }, 7 | "api-key": { 8 | "name": "api-key", 9 | "type": "api-key", 10 | "disabled": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/compensating-write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/apps/error-handling/compensating-write.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/data_sources/mongodb-atlas/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongodb-atlas", 3 | "type": "mongodb-atlas", 4 | "config": { 5 | "clusterName": "Cluster0", 6 | "readPreference": "primary", 7 | "wireProtocolEnabled": false 8 | }, 9 | "version": 1 10 | } 11 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/data_sources/mongodb-atlas/default_rule.json: -------------------------------------------------------------------------------- 1 | { 2 | "roles": [ 3 | { 4 | "name": "readOwnWriteOwn", 5 | "apply_when": {}, 6 | "document_filters": { 7 | "write": { 8 | "owner_id": "%%user.id" 9 | }, 10 | "read": { 11 | "owner_id": "%%user.id" 12 | } 13 | }, 14 | "read": true, 15 | "write": true, 16 | "insert": true, 17 | "delete": true, 18 | "search": true 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/data_sources/mongodb-atlas/error-handling/Entry/relationships.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/data_sources/mongodb-atlas/error-handling/Entry/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "_id": { 4 | "bsonType": "objectId" 5 | }, 6 | "owner_id": { 7 | "bsonType": "string" 8 | } 9 | }, 10 | "required": [ 11 | "_id", 12 | "owner_id" 13 | ], 14 | "title": "Entry", 15 | "type": "object" 16 | } 17 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/environments/development.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/environments/no-environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/environments/production.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/environments/qa.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/environments/testing.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/functions/config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "triggerClientReset", 4 | "private": false, 5 | "run_as_system": true, 6 | "disable_arg_logs": true 7 | } 8 | ] 9 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/functions/triggerClientReset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WARNING: THIS FUNCTION EXISTS FOR DEMO PORPUSES AND SHOULD NOT BE USED IN PRODUCTION. 3 | */ 4 | exports = async function(arg){ 5 | const clientFilesCollection = context.services 6 | .get("mongodb-atlas") 7 | .db("__realm_sync_" + context.app.id) 8 | .collection("clientfiles"); 9 | 10 | try { 11 | let result = await clientFilesCollection.deleteMany( 12 | { 13 | ownerId: context.user.id, 14 | } 15 | ); 16 | return result.deletedCount; 17 | } catch (e) { 18 | console.error(`Failed to delete client file for user: ${context.user.id}`); 19 | throw e 20 | } 21 | }; -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/graphql/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "use_natural_pluralization": true 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/http_endpoints/config.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/realm_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "app_id": "error-handling-jltyk", 3 | "config_version": 20210101, 4 | "name": "error-handling", 5 | "location": "IE", 6 | "provider_region": "aws-eu-west-1", 7 | "deployment_model": "LOCAL" 8 | } 9 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/step1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/apps/error-handling/step1.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/step2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/apps/error-handling/step2.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/step3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/apps/error-handling/step3.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/step4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/apps/error-handling/step4.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/error-handling/sync/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "flexible", 3 | "state": "enabled", 4 | "development_mode_enabled": true, 5 | "service_name": "mongodb-atlas", 6 | "database_name": "error-handling", 7 | "client_max_offline_days": 30, 8 | "is_recovery_mode_disabled": false, 9 | "permissions": { 10 | "rules": {}, 11 | "defaultRoles": [] 12 | }, 13 | "queryable_fields_names": [ 14 | "owner_id" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/auth/custom_user_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/auth/providers.json: -------------------------------------------------------------------------------- 1 | { 2 | "anon-user": { 3 | "name": "anon-user", 4 | "type": "anon-user", 5 | "disabled": false 6 | }, 7 | "api-key": { 8 | "name": "api-key", 9 | "type": "api-key", 10 | "disabled": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/data_sources/mongodb-atlas/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongodb-atlas", 3 | "type": "mongodb-atlas", 4 | "config": { 5 | "clusterName": "Cluster0", 6 | "readPreference": "primary", 7 | "wireProtocolEnabled": false 8 | }, 9 | "version": 1 10 | } 11 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/data_sources/mongodb-atlas/default_rule.json: -------------------------------------------------------------------------------- 1 | { 2 | "roles": [ 3 | { 4 | "name": "readAll", 5 | "apply_when": {}, 6 | "document_filters": { 7 | "write": false, 8 | "read": true 9 | }, 10 | "read": true, 11 | "write": false, 12 | "insert": false, 13 | "delete": false, 14 | "search": true 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/data_sources/mongodb-atlas/presence-detection/user_status/relationships.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/data_sources/mongodb-atlas/presence-detection/user_status/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "_id": { 4 | "bsonType": "objectId" 5 | }, 6 | "owner_id": { 7 | "bsonType": "string" 8 | }, 9 | "present": { 10 | "bsonType": "bool" 11 | } 12 | }, 13 | "required": [ 14 | "_id", 15 | "present", 16 | "owner_id" 17 | ], 18 | "title": "user_status", 19 | "type": "object" 20 | } 21 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/environments/development.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/environments/no-environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/environments/production.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/environments/qa.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/environments/testing.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/functions/config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "logPresenceDetector", 4 | "private": false 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/functions/logPresenceDetector.js: -------------------------------------------------------------------------------- 1 | exports = async function (logs) { 2 | // logs appear in ascending order 3 | for (let i = logs.length - 1; i >= 0; i--) { 4 | extract_presence(logs[i]) 5 | } 6 | }; 7 | 8 | async function extract_presence(log) { 9 | let type = log.type 10 | if (type !== "SYNC_SESSION_START" && type !== "SYNC_SESSION_END") return; 11 | 12 | let user_id = log.user_id; 13 | let present = type === "SYNC_SESSION_START"; 14 | 15 | console.log(`User ${user_id} present: ${present}`); 16 | 17 | update_presence(user_id, present); 18 | } 19 | 20 | async function update_presence(user_id, present) { 21 | const customUserDataCollection = context.services 22 | .get("mongodb-atlas") 23 | .db("presence-detection") 24 | .collection("user_status"); 25 | 26 | try { 27 | await customUserDataCollection.updateOne( 28 | { 29 | owner_id: user_id, 30 | }, 31 | { 32 | owner_id: user_id, 33 | present: present 34 | }, 35 | { 36 | upsert: true 37 | } 38 | ); 39 | } catch (e) { 40 | console.error(`Failed to create custom user data document for user: ${user_id}`); 41 | throw e 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/graphql/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "use_natural_pluralization": true 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/http_endpoints/config.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/log_forwarders/presenceDetector.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "presenceDetector", 3 | "log_types": [ 4 | "sync" 5 | ], 6 | "log_statuses": [ 7 | "success" 8 | ], 9 | "policy": { 10 | "type": "batch" 11 | }, 12 | "action": { 13 | "type": "function", 14 | "name": "logPresenceDetector" 15 | }, 16 | "disabled": false 17 | } 18 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/apps/presence-detection/logs.png -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/realm_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "app_id": "presence-detection", 3 | "config_version": 20210101, 4 | "name": "presence-detection", 5 | "location": "IE", 6 | "provider_region": "aws-eu-west-1", 7 | "deployment_model": "LOCAL" 8 | } 9 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/presence-detection/sync/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "flexible", 3 | "state": "enabled", 4 | "development_mode_enabled": false, 5 | "service_name": "mongodb-atlas", 6 | "database_name": "presence-detection", 7 | "client_max_offline_days": 30, 8 | "is_recovery_mode_disabled": false, 9 | "permissions": { 10 | "rules": {}, 11 | "defaultRoles": [] 12 | }, 13 | "queryable_fields_names": [ 14 | "owner_id" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/auth/custom_user_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": true, 3 | "mongo_service_name": "mongodb-atlas", 4 | "database_name": "property_encryption", 5 | "collection_name": "custom_data", 6 | "user_id_field": "owner_id", 7 | "on_user_creation_function_name": "initializeCustomData" 8 | } 9 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/auth/providers.json: -------------------------------------------------------------------------------- 1 | { 2 | "anon-user": { 3 | "name": "anon-user", 4 | "type": "anon-user", 5 | "disabled": true 6 | }, 7 | "api-key": { 8 | "name": "api-key", 9 | "type": "api-key", 10 | "disabled": true 11 | }, 12 | "local-userpass": { 13 | "name": "local-userpass", 14 | "type": "local-userpass", 15 | "config": { 16 | "autoConfirm": true, 17 | "resetPasswordSubject": "Dummy password reset settings", 18 | "resetPasswordUrl": "https://www.dummy-domain.com/reset", 19 | "runConfirmationFunction": false, 20 | "runResetFunction": false 21 | }, 22 | "disabled": false 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/data_sources/mongodb-atlas/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongodb-atlas", 3 | "type": "mongodb-atlas", 4 | "config": { 5 | "clusterName": "Cluster0", 6 | "readPreference": "primary", 7 | "wireProtocolEnabled": false 8 | }, 9 | "version": 1 10 | } 11 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/data_sources/mongodb-atlas/default_rule.json: -------------------------------------------------------------------------------- 1 | { 2 | "roles": [ 3 | { 4 | "name": "readOwnWriteOwn", 5 | "apply_when": {}, 6 | "document_filters": { 7 | "write": { 8 | "owner_id": "%%user.id" 9 | }, 10 | "read": { 11 | "owner_id": "%%user.id" 12 | } 13 | }, 14 | "read": true, 15 | "write": true, 16 | "insert": true, 17 | "delete": true, 18 | "search": true 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/data_sources/mongodb-atlas/field_encryption/custom_data/relationships.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/data_sources/mongodb-atlas/field_encryption/custom_data/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "custom_data", 3 | "type": "object", 4 | "required": [], 5 | "properties": { 6 | "_id": { 7 | "bsonType": "objectId" 8 | }, 9 | "ple_cipher_spec": { 10 | "title": "custom_data_ple_cipher_spec", 11 | "type": "object", 12 | "required": [], 13 | "properties": { 14 | "algorithm": { 15 | "bsonType": "string" 16 | }, 17 | "block": { 18 | "bsonType": "string" 19 | }, 20 | "key_length": { 21 | "bsonType": "long" 22 | }, 23 | "padding": { 24 | "bsonType": "string" 25 | } 26 | } 27 | }, 28 | "key_store": { 29 | "bsonType": "binData" 30 | }, 31 | "owner_id": { 32 | "bsonType": "string" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/data_sources/mongodb-atlas/field_encryption/secret_record/relationships.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/data_sources/mongodb-atlas/field_encryption/secret_record/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "_id": { 4 | "bsonType": "objectId" 5 | }, 6 | "owner_id": { 7 | "bsonType": "string" 8 | }, 9 | "securedContent": { 10 | "bsonType": "binData" 11 | } 12 | }, 13 | "required": [ 14 | "_id", 15 | "owner_id", 16 | "securedContent" 17 | ], 18 | "title": "secret_record", 19 | "type": "object" 20 | } 21 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/environments/development.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/environments/no-environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/environments/production.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/environments/qa.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/environments/testing.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": {} 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/functions/config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "initializeCustomData", 4 | "private": false 5 | }, 6 | { 7 | "name": "updateKeyStore", 8 | "private": false 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/functions/initializeCustomData.js: -------------------------------------------------------------------------------- 1 | // Executing this function would generate a new encryption key and store it in the user custom data 2 | exports = async function (user) { 3 | const customUserDataCollection = context.services 4 | .get("mongodb-atlas") 5 | .db("property_encryption") 6 | .collection("custom_data"); 7 | 8 | try { 9 | await customUserDataCollection.insertOne({ 10 | // Bind this user custom data to the new user 11 | owner_id: user.id, 12 | // Algorithm spec for property level encryption 13 | ple_cipher_spec: { 14 | algorithm: "AES", 15 | block: "CBC", 16 | padding: "PKCS7Padding", 17 | key_length: 128 18 | }, 19 | // Uninitialized BKS keystore 20 | key_store: null 21 | }); 22 | } catch (e) { 23 | console.error(`Failed to create custom user data document for user: ${user.id}`); 24 | throw e 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/functions/updateKeyStore.js: -------------------------------------------------------------------------------- 1 | exports = async function (arg) { 2 | const customUserDataCollection = context.services 3 | .get("mongodb-atlas") 4 | .db("property_encryption") 5 | .collection("custom_data"); 6 | 7 | try { 8 | await customUserDataCollection.updateOne( 9 | { 10 | // Update the users custom data 11 | owner_id: context.user.id 12 | }, 13 | { 14 | $set: { key_store: arg } 15 | } 16 | ); 17 | return true; 18 | } catch (e) { 19 | console.error(`Failed to create custom user data document for user: ${context.user.id}`); 20 | throw e 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/graphql/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "use_natural_pluralization": true 3 | } 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/http_endpoints/config.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/realm_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "app_id": "property-encryption-fjrvt", 3 | "config_version": 20210101, 4 | "name": "property-encryption", 5 | "location": "IE", 6 | "provider_region": "aws-eu-west-1", 7 | "deployment_model": "LOCAL" 8 | } 9 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/apps/property-encryption/sync/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "flexible", 3 | "state": "enabled", 4 | "development_mode_enabled": false, 5 | "service_name": "mongodb-atlas", 6 | "database_name": "property_encryption", 7 | "client_max_offline_days": 30, 8 | "is_recovery_mode_disabled": false, 9 | "permissions": { 10 | "rules": {}, 11 | "defaultRoles": [] 12 | }, 13 | "queryable_fields_names": [ 14 | "owner_id" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/build.gradle.kts: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | plugins { 3 | alias(libs.plugins.android.application) apply false 4 | alias(libs.plugins.android.library) apply false 5 | alias(libs.plugins.kotlin.android) apply false 6 | } 7 | 8 | // Explicitly adding the plugin to the classpath as it makes it easier to control the version 9 | // centrally (don't need version in the 'plugins' block). Further, snapshots are not published with 10 | // marker interface so would need to be added to the classpath manually anyway. 11 | buildscript { 12 | dependencies { 13 | classpath(libs.realm.plugin) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/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. 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 -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/assets/certificate.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICljCCAX4CCQCyCmupaumxZTANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJE 3 | SzAeFw0yMzA2MjAyMTU1MzRaFw0yNDA2MTkyMTU1MzRaMA0xCzAJBgNVBAYTAkRL 4 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt/VQdsQOskZ1ucjPeZ/1 5 | ka2XiRv9umVkTv7sFJkVA/pkVaB4khWanxGn92+ikqhkY0V4Fr0FbnBtjkwU+uDE 6 | nV6E8k5yU7xm2kKZhLhIEmoBWOgF04S/MV3gMDn/lQKKtIKBxnvcVVJfm5wJmjH5 7 | PYNJ9viTRd98kWFCuogiSFh6GvglYIOkPsv1axffoju5QXOviNA/IFZplq5WesM4 8 | 5lGvw8pvRbWrecE6EZb3kl/fLSNrAKBxKqPtN1GNL43uRp0+WrO8zWfOPmUK8PCH 9 | XjZMTxNJ0tVRuroMmvmin2BV3W0kTDPaZLB2bLwv9avKRbdADMBD8Vef4OojqG/S 10 | WwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCIEz0x7ppsiQgFxGe1lDPHdIWhzul3 11 | /lSyvxXn2euebIOlJv6R4g1TTGfnh6A5yR8ELIO8x0lWWW7VvVewG3M0ANIk1XDq 12 | emYO9CLnGK58vEKfL+1cTemwMrh7Lmzq0P2q25xs/ZIKUtvgvNkhwDXF91iABe9G 13 | SDpawDbqjn1eSA2aon1P61F+W2lpqTZlza5JoJJspRLRTqDL2Tu/xmLN/9ZnpBaz 14 | KcG0cr309vvTBEI5NfcPpNS+YGTF+rQF0CV0yoBcsBMEa/DapE6zW3aoZKIYV6OP 15 | Sv3N2CS6awU/Iu9t8e2SrDQVD8sRPBK9RbSUQavmKspRoCUZ1/tECfuW 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/Constants.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples 18 | 19 | // Replace any with the App Services app id sample. 20 | // It is not mandatory to have them all replaced, only the samples to evaluate. 21 | const val PROPERTY_ENCRYPTION_APP_ID = "" 22 | const val USER_PRESENCE_APP_ID = "" 23 | const val ERROR_HANDLING_APP_ID = "" 24 | const val DYNAMIC_DATA_APP_ID = "" 25 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/dynamicdata/DependencyInjection.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples.dynamicdata 18 | 19 | import io.realm.appservicesusagesamples.Demos 20 | import io.realm.appservicesusagesamples.dynamicdata.ui.DynamicDataViewModel 21 | import io.realm.appservicesusagesamples.presence.ui.UserStatusListViewModel 22 | import org.koin.androidx.viewmodel.dsl.viewModel 23 | import org.koin.dsl.module 24 | 25 | val dynamicDataViewModel = module { 26 | viewModel { 27 | DynamicDataViewModel( 28 | app = get(qualifier = Demos.DYNAMIC_DATA.qualifier), 29 | ) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/dynamicdata/models/DynamicDataEntity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples.dynamicdata.models 18 | 19 | import io.realm.kotlin.types.RealmAny 20 | import io.realm.kotlin.types.RealmObject 21 | import io.realm.kotlin.types.annotations.PersistedName 22 | import io.realm.kotlin.types.annotations.PrimaryKey 23 | import org.mongodb.kbson.BsonObjectId 24 | import org.mongodb.kbson.ObjectId 25 | 26 | class DynamicDataEntity: RealmObject { 27 | @PersistedName("_id") 28 | @PrimaryKey 29 | var id: ObjectId = BsonObjectId() 30 | 31 | var name: String = "" 32 | 33 | var configuration: RealmAny? = null 34 | } 35 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/errorhandling/DependencyInjection.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples.errorhandling 18 | 19 | import io.realm.appservicesusagesamples.Demos 20 | import io.realm.appservicesusagesamples.errorhandling.ui.ErrorHandlingViewModel 21 | import io.realm.appservicesusagesamples.presence.ui.UserStatusListViewModel 22 | import org.koin.androidx.viewmodel.dsl.viewModel 23 | import org.koin.dsl.module 24 | 25 | val errorHandlingModule = module { 26 | scope { 27 | factory { params -> 28 | ErrorHandlingViewModel( 29 | app = get(qualifier = Demos.ERROR_HANDLING.qualifier), 30 | clientResetAction = params.get(), 31 | ) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/errorhandling/models/Entry.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples.errorhandling.models 18 | 19 | import io.realm.kotlin.types.RealmObject 20 | import io.realm.kotlin.types.annotations.PersistedName 21 | import io.realm.kotlin.types.annotations.PrimaryKey 22 | import org.mongodb.kbson.BsonObjectId 23 | 24 | class Entry: RealmObject { 25 | @PrimaryKey 26 | @PersistedName("_id") 27 | var id = BsonObjectId() 28 | 29 | @PersistedName("owner_id") 30 | var ownerId: String = "" 31 | } -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/presence/DependencyInjection.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples.presence 18 | 19 | import io.realm.appservicesusagesamples.Demos 20 | import io.realm.appservicesusagesamples.presence.ui.UserStatusListViewModel 21 | import org.koin.androidx.viewmodel.dsl.viewModel 22 | import org.koin.dsl.module 23 | 24 | val presenceDetectionModule = module { 25 | viewModel { 26 | UserStatusListViewModel( 27 | app = get(qualifier = Demos.USER_PRESENCE.qualifier), 28 | ) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/presence/models/UserStatus.kt: -------------------------------------------------------------------------------- 1 | package io.realm.appservicesusagesamples.presence.models 2 | 3 | import io.realm.kotlin.types.RealmObject 4 | import io.realm.kotlin.types.annotations.PersistedName 5 | import io.realm.kotlin.types.annotations.PrimaryKey 6 | import org.mongodb.kbson.ObjectId 7 | 8 | @PersistedName("user_status") 9 | class UserStatus : RealmObject { 10 | @PersistedName("_id") 11 | @PrimaryKey 12 | var id: ObjectId = ObjectId() 13 | @PersistedName("owner_id") 14 | var ownerId: String = "" 15 | var present: Boolean = false 16 | } -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/propertyencryption/ext/EncryptionExt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples.propertyencryption.ext 18 | 19 | import io.realm.appservicesusagesamples.propertyencryption.models.SerializableCipherSpec 20 | import javax.crypto.KeyGenerator 21 | import javax.crypto.SecretKey 22 | 23 | /** 24 | * Generates a new key for the given cipher specification. 25 | */ 26 | fun SerializableCipherSpec.generateKey(): SecretKey = 27 | KeyGenerator 28 | .getInstance( 29 | /* algorithm = */ algorithm 30 | ).apply { 31 | init(keyLength) 32 | } 33 | .generateKey() 34 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/java/io/realm/appservicesusagesamples/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | * or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.realm.appservicesusagesamples.ui.theme 18 | 19 | import androidx.compose.ui.graphics.Color 20 | 21 | val Purple80 = Color(0xFFD0BCFF) 22 | val PurpleGrey80 = Color(0xFFCCC2DC) 23 | val Pink80 = Color(0xFFEFB8C8) 24 | 25 | val Purple40 = Color(0xFF6650a4) 26 | val PurpleGrey40 = Color(0xFF625b71) 27 | val Pink40 = Color(0xFF7D5260) -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/drawable/baseline_cancel_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/drawable/baseline_check_circle_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/AppServicesUsageSamples/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | App Services Usage Samples 3 | DemoSelectorActivity 4 | -------------------------------------------------------------------------------- /AppServicesUsageSamples/demo/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 8 | -------------------------------------------------------------------------------- /Bookshelf/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.kotlinMultiplatform) apply false 3 | alias(libsx.plugins.kotlinAndroid) apply false 4 | alias(libsx.plugins.androidApplication) apply false 5 | alias(libsx.plugins.androidLibrary) apply false 6 | } 7 | 8 | // Explicitly adding the plugin to the classpath as it makes it easier to control the version 9 | // centrally (don't need version in the 'plugins' block). Further, snapshots are not published with 10 | // marker interface so would need to be added to the classpath manually anyway. 11 | buildscript { 12 | dependencies { 13 | classpath(libsx.realm.plugin) 14 | } 15 | } 16 | 17 | allprojects { 18 | group = "io.realm.sample.bookshelf" 19 | version = "1.0.0" 20 | } 21 | 22 | tasks.register("clean", Delete::class) { 23 | delete(rootProject.buildDir) 24 | } 25 | -------------------------------------------------------------------------------- /Bookshelf/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/Bookshelf/debug.keystore -------------------------------------------------------------------------------- /Bookshelf/gradle.properties: -------------------------------------------------------------------------------- 1 | #Gradle 2 | org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" 3 | 4 | #Kotlin 5 | kotlin.code.style=official 6 | 7 | #Android 8 | android.useAndroidX=true -------------------------------------------------------------------------------- /Bookshelf/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/Bookshelf/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Bookshelf/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020 Realm Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | # or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | #Wed Aug 26 08:28:57 MSK 2020 19 | distributionBase=GRADLE_USER_HOME 20 | distributionPath=wrapper/dists 21 | zipStoreBase=GRADLE_USER_HOME 22 | zipStorePath=wrapper/dists 23 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 24 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Podfile: -------------------------------------------------------------------------------- 1 | target 'iosApp' do 2 | use_frameworks! 3 | platform :ios, '14.1' 4 | pod 'shared', :path => '../shared' 5 | end -------------------------------------------------------------------------------- /Bookshelf/iosApp/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared" 10 | 11 | SPEC CHECKSUMS: 12 | shared: 8d306cf673b31688e42c9240be260231b3f39192 13 | 14 | PODFILE CHECKSUM: f282da88f39e69507b0a255187c8a6b644477756 15 | 16 | COCOAPODS: 1.11.3 17 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared" 10 | 11 | SPEC CHECKSUMS: 12 | shared: 8d306cf673b31688e42c9240be260231b3f39192 13 | 14 | PODFILE CHECKSUM: f282da88f39e69507b0a255187c8a6b644477756 15 | 16 | COCOAPODS: 1.11.3 17 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_iosApp : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_iosApp 5 | @end 6 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_iosAppVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_iosAppVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | ENABLE_USER_SCRIPT_SANDBOXING = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -l"c++" -framework "shared" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | ENABLE_USER_SCRIPT_SANDBOXING = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -l"c++" -framework "shared" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/shared/shared.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/shared 3 | ENABLE_USER_SCRIPT_SANDBOXING = NO 4 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 5 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 6 | KOTLIN_PROJECT_PATH = :shared 7 | OTHER_LDFLAGS = $(inherited) -l"c++" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT} 11 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../shared 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 14 | PRODUCT_MODULE_NAME = shared 15 | SKIP_INSTALL = YES 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/Pods/Target Support Files/shared/shared.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/shared 3 | ENABLE_USER_SCRIPT_SANDBOXING = NO 4 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../../shared/build/cocoapods/framework" 5 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 6 | KOTLIN_PROJECT_PATH = :shared 7 | OTHER_LDFLAGS = $(inherited) -l"c++" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT} 11 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../shared 12 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 13 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 14 | PRODUCT_MODULE_NAME = shared 15 | SKIP_INSTALL = YES 16 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 17 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/iosApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/iosApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Bookshelf/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } -------------------------------------------------------------------------------- /Bookshelf/iosApp/iosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } -------------------------------------------------------------------------------- /Bookshelf/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } -------------------------------------------------------------------------------- /Bookshelf/iosApp/iosApp/iOSApp.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import SwiftUI 17 | 18 | @main 19 | struct iOSApp: App { 20 | var body: some Scene { 21 | WindowGroup { 22 | ContentView() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Bookshelf/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | // Only required for realm-kotlin snapshots 7 | maven("https://oss.sonatype.org/content/repositories/snapshots") 8 | } 9 | } 10 | 11 | dependencyResolutionManagement { 12 | versionCatalogs { 13 | create("libsx") { 14 | from(files("../versions/current.toml")) 15 | } 16 | } 17 | repositories { 18 | google() 19 | mavenCentral() 20 | // Only required for realm-kotlin snapshots 21 | maven("https://oss.sonatype.org/content/repositories/snapshots") 22 | } 23 | } 24 | 25 | rootProject.name = "Bookshelf" 26 | include(":androidApp") 27 | include(":shared") 28 | -------------------------------------------------------------------------------- /Bookshelf/shared/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Bookshelf/shared/src/commonMain/kotlin/io/realm/sample/bookshelf/model/Book.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.sample.bookshelf.model 18 | 19 | import io.realm.kotlin.types.RealmList 20 | import io.realm.kotlin.types.RealmObject 21 | import io.realm.kotlin.ext.realmListOf 22 | 23 | class Book : RealmObject { 24 | 25 | var subtitle: String? = "" 26 | var title: String = "" 27 | var editionCount: Int? = null 28 | var firstPublishYear: Int? = null 29 | var imgId: String? = null 30 | var authors: RealmList = realmListOf() 31 | 32 | companion object { 33 | private const val BOOK_COVER_URL = "https://covers.openlibrary.org/b/id/" 34 | } 35 | 36 | fun getImageURL(): String { 37 | return "$BOOK_COVER_URL$imgId-M.jpg" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Bookshelf/shared/src/commonMain/kotlin/io/realm/sample/bookshelf/network/SearchResult.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.sample.bookshelf.network 18 | 19 | import kotlinx.serialization.SerialName 20 | import kotlinx.serialization.Serializable 21 | 22 | @Serializable 23 | data class SearchResult( 24 | @SerialName("numFound") val numberOrResults: Int, 25 | @SerialName("docs") val books: List 26 | ) 27 | -------------------------------------------------------------------------------- /Intro/README.md: -------------------------------------------------------------------------------- 1 | # Realm KMM Sample 2 | 3 | A _Kotlin (KMM) Project_ showing usage of Realm Kotlin in a shared module of a 4 | multiplatform project for both Android and iOS. 5 | 6 | The example is based on the Kotlin Multiplatform Mobile Project from 7 | https://github.com/Kotlin/kmm-sample/blob/master/README.md 8 | 9 | ## Requirements 10 | 11 | - JDK 11 12 | - Android Studio [Dolphin (2021.3.1)](https://developer.android.com/studio) 13 | 14 | ## Overview 15 | 16 | The Realm Kotlin Multiplatform SDK is used to provide a common implementation of an 17 | `ExpressionRepository` for storing a computation history of calculations performed in the respective 18 | apps. The repository is implemented once in the `commonMain` source set of the `shared`-module and 19 | is triggered by the shared `Calculator`-implementation from the original KMM-sample project. 20 | 21 | ## References 22 | 23 | For instructions on developing Kotlin Multiplatform Mobile Project, visit 24 | [Kotlin Multiplatform Mobile Developer Portal](https://kotlinlang.org/lp/mobile/). 25 | -------------------------------------------------------------------------------- /Intro/Screenshots/Android/Home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/Intro/Screenshots/Android/Home.png -------------------------------------------------------------------------------- /Intro/Screenshots/iOS/Home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/Intro/Screenshots/iOS/Home.png -------------------------------------------------------------------------------- /Intro/androidApp/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | #FF6200EE 21 | #FF3700B3 22 | #FF03DAC5 23 | #FF018786 24 | #FF000000 25 | #FFFFFFFF 26 | 27 | -------------------------------------------------------------------------------- /Intro/androidApp/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Intro/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.kotlinMultiplatform) apply false 3 | alias(libsx.plugins.kotlinAndroid) apply false 4 | alias(libsx.plugins.androidApplication) apply false 5 | alias(libsx.plugins.androidLibrary) apply false 6 | } 7 | 8 | // Explicitly adding the plugin to the classpath as it makes it easier to control the version 9 | // centrally (don't need version in the 'plugins' block). Further, snapshots are not published with 10 | // marker interface so would need to be added to the classpath manually anyway. 11 | buildscript { 12 | dependencies { 13 | classpath(libsx.realm.plugin) 14 | } 15 | } 16 | 17 | group = "io.realm.example" 18 | version = "1.0.0" 19 | -------------------------------------------------------------------------------- /Intro/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/Intro/debug.keystore -------------------------------------------------------------------------------- /Intro/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020 Realm Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | # or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | org.gradle.jvmargs=-Xms512m -Xmx2048m 19 | 20 | kotlin.code.style=official 21 | xcodeproj=./iosApp 22 | android.useAndroidX=true 23 | 24 | kotlin.mpp.stability.nowarn=true 25 | -------------------------------------------------------------------------------- /Intro/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/Intro/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Intro/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020 Realm Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 | # or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | #Wed Aug 26 08:28:57 MSK 2020 19 | distributionBase=GRADLE_USER_HOME 20 | distributionPath=wrapper/dists 21 | zipStoreBase=GRADLE_USER_HOME 22 | zipStorePath=wrapper/dists 23 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 24 | 25 | -------------------------------------------------------------------------------- /Intro/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Intro/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Intro/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } -------------------------------------------------------------------------------- /Intro/iosApp/iosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } -------------------------------------------------------------------------------- /Intro/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } -------------------------------------------------------------------------------- /Intro/iosApp/iosApp/iOSApp.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct iOSApp: App { 5 | var body: some Scene { 6 | WindowGroup { 7 | ContentView() 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Intro/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | // If you want to run against the local source repository just include the source projects by 2 | // reincluding the below 3 | // includeBuild("/packages") 4 | 5 | pluginManagement { 6 | repositories { 7 | google() 8 | gradlePluginPortal() 9 | mavenCentral() 10 | // Only required for realm-kotlin snapshots 11 | maven("https://oss.sonatype.org/content/repositories/snapshots") 12 | } 13 | } 14 | 15 | dependencyResolutionManagement { 16 | versionCatalogs { 17 | create("libsx") { 18 | from(files("../versions/current.toml")) 19 | } 20 | } 21 | repositories { 22 | google() 23 | mavenCentral() 24 | // Only required for realm-kotlin snapshots 25 | maven("https://oss.sonatype.org/content/repositories/snapshots") 26 | } 27 | } 28 | 29 | rootProject.name = "KmmSample" 30 | 31 | include(":androidApp") 32 | include(":shared") 33 | -------------------------------------------------------------------------------- /Intro/shared/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Intro/shared/src/androidMain/kotlin/io/realm/example/kmmsample/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | @Suppress("EmptyDefaultConstructor", "MemberNameEqualsClassName") 22 | actual class Platform actual constructor() { 23 | actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}" 24 | } 25 | -------------------------------------------------------------------------------- /Intro/shared/src/androidTest/kotlin/io/realm/example/kmmsample/GreetingTestAndroid.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | import androidx.test.ext.junit.runners.AndroidJUnit4 22 | import org.junit.Assert 23 | import org.junit.Test 24 | import org.junit.runner.RunWith 25 | 26 | @RunWith(AndroidJUnit4::class) 27 | class GreetingTestAndroid { 28 | 29 | @Test 30 | fun testExample() { 31 | Assert.assertTrue("Check Android is mentioned", Greeting().greeting().contains("Android")) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Intro/shared/src/commonMain/kotlin/io/realm/example/kmmsample/Expression.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | import io.realm.kotlin.types.RealmObject 22 | 23 | class Expression : RealmObject { 24 | var expressionString: String = "" 25 | } 26 | -------------------------------------------------------------------------------- /Intro/shared/src/commonMain/kotlin/io/realm/example/kmmsample/Greeting.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | class Greeting { 22 | @Suppress("MemberNameEqualsClassName") 23 | fun greeting(): String { 24 | return "Hello, ${Platform().platform}!" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Intro/shared/src/commonMain/kotlin/io/realm/example/kmmsample/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | @Suppress("EmptyDefaultConstructor", "MemberNameEqualsClassName") 22 | expect class Platform() { 23 | val platform: String 24 | } 25 | -------------------------------------------------------------------------------- /Intro/shared/src/commonTest/kotlin/io/realm/example/kmmsample/CalculatorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | import kotlin.test.Test 22 | import kotlin.test.assertEquals 23 | 24 | class CalculatorTest { 25 | 26 | @Test 27 | fun testSum() { 28 | assertEquals(3, Calculator.sum(1, 2)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Intro/shared/src/commonTest/kotlin/io/realm/example/kmmsample/ExpressionRepositoryTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | import kotlin.test.Test 22 | import kotlin.test.assertEquals 23 | 24 | class ExpressionRepositoryTest { 25 | 26 | @Test 27 | fun insert() { 28 | val repository = ExpressionRepository() 29 | val expression = repository.addExpression("a + b") 30 | assertEquals("a + b", expression.expressionString) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Intro/shared/src/iosMain/kotlin/io/realm/example/kmmsample/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | import platform.UIKit.UIDevice 22 | 23 | @Suppress("EmptyDefaultConstructor", "MemberNameEqualsClassName") 24 | actual class Platform actual constructor() { 25 | actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion 26 | } 27 | -------------------------------------------------------------------------------- /Intro/shared/src/iosTest/kotlin/io/realm/example/kmmsample/GreetingTestIos.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 JetBrains s.r.o. 3 | * Copyright 2020 Realm Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 | * or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package io.realm.example.kmmsample 20 | 21 | import kotlin.test.Test 22 | import kotlin.test.assertTrue 23 | 24 | class GreetingTestIos { 25 | 26 | @Test 27 | fun testExample() { 28 | assertTrue(Greeting().greeting().contains("iOS"), "Check iOS is mentioned") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /JVMConsole/README.md: -------------------------------------------------------------------------------- 1 | # Simple Java Console Application using Realm-Kotlin. 2 | 3 | 4 | 5 | This application demonstrates the usage of Realm Kotlin SDK in a regular console app (no Multiplatform). 6 | It is powered by Kotlin/JVM support from Realm-Kotlin SDK. 7 | 8 | ## Run from IntelliJ IDEA 9 | 10 | Navigate to `src/main/kotlin/io.realm/example/main.kt` 11 | Click on `Run MainKt` 12 | 13 | 14 | ## Standalone jar 15 | 16 | ```Gradle 17 | ./gradlew clean jar 18 | java -jar build/libs/JVM_Console-1.0.0.jar 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /JVMConsole/Screenshots/Console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/JVMConsole/Screenshots/Console.png -------------------------------------------------------------------------------- /JVMConsole/Screenshots/DemoConsoleJVM.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/JVMConsole/Screenshots/DemoConsoleJVM.gif -------------------------------------------------------------------------------- /JVMConsole/Screenshots/run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/JVMConsole/Screenshots/run.png -------------------------------------------------------------------------------- /JVMConsole/gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | -------------------------------------------------------------------------------- /JVMConsole/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/JVMConsole/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /JVMConsole/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /JVMConsole/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | mavenCentral() 5 | // Only required for realm-kotlin snapshots 6 | maven("https://oss.sonatype.org/content/repositories/snapshots") 7 | } 8 | } 9 | dependencyResolutionManagement { 10 | versionCatalogs { 11 | create("libsx") { 12 | from(files("../versions/current.toml")) 13 | } 14 | } 15 | } 16 | rootProject.name = "JVM_Console" 17 | 18 | -------------------------------------------------------------------------------- /JavaKotlinMavenInterop/Screenshots/java-kotlin-maven-interop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/JavaKotlinMavenInterop/Screenshots/java-kotlin-maven-interop.png -------------------------------------------------------------------------------- /JavaKotlinMavenInterop/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.kotlinJvm) apply false 3 | } 4 | 5 | // Explicitly adding the plugin to the classpath as it makes it easier to control the version 6 | // centrally (don't need version in the 'plugins' block). Further, snapshots are not published with 7 | // marker interface so would need to be added to the classpath manually anyway. 8 | buildscript { 9 | dependencies { 10 | classpath(libsx.realm.plugin) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /JavaKotlinMavenInterop/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/JavaKotlinMavenInterop/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /JavaKotlinMavenInterop/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /JavaKotlinMavenInterop/java-app-gradle/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | application 4 | } 5 | 6 | group = "com.mongodb.devicesync" 7 | version = "1.0.0-SNAPSHOT" 8 | 9 | repositories { 10 | mavenCentral() 11 | maven("https://oss.sonatype.org/content/repositories/snapshots") 12 | } 13 | 14 | dependencies { 15 | implementation(project(":kotlin-lib")) 16 | } 17 | 18 | application { 19 | mainClass.set("com.mongodb.devicesync.javainterop.gradle.JavaGradleApp") 20 | } 21 | 22 | java { 23 | toolchain { 24 | languageVersion.set(JavaLanguageVersion.of(11)) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /JavaKotlinMavenInterop/kotlin-lib/src/main/kotlin/com/mongodb/devicesync/kotlin/Schema.kt: -------------------------------------------------------------------------------- 1 | package com.mongodb.devicesync.kotlin 2 | 3 | import io.realm.kotlin.ext.realmListOf 4 | import io.realm.kotlin.types.RealmList 5 | import io.realm.kotlin.types.RealmObject 6 | import io.realm.kotlin.types.annotations.PersistedName 7 | import io.realm.kotlin.types.annotations.PrimaryKey 8 | import org.mongodb.kbson.ObjectId 9 | 10 | class Person: RealmObject { 11 | @PrimaryKey 12 | @PersistedName("_id") 13 | var id = ObjectId() 14 | var name: String = "" 15 | var age: Int = 0 16 | var children: RealmList = realmListOf() 17 | var favoriteChild: Child? = null 18 | 19 | // Expose method making it easier to use from Java 20 | fun setChildren(children: ArrayList) { 21 | children.addAll(children) 22 | } 23 | 24 | override fun toString(): String { 25 | return "Person(id=$id, name='$name', age=$age, children=$children, favoriteChild=$favoriteChild)" 26 | } 27 | } 28 | 29 | class Child(s: String) : RealmObject { 30 | // No-arg constructor required by Realm 31 | constructor(): this("") 32 | @PrimaryKey 33 | @PersistedName("_id") 34 | var id = ObjectId() 35 | var name: String = s 36 | } -------------------------------------------------------------------------------- /JavaKotlinMavenInterop/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") 7 | // Only required for realm-kotlin snapshots 8 | maven("https://oss.sonatype.org/content/repositories/snapshots") 9 | } 10 | } 11 | 12 | dependencyResolutionManagement { 13 | versionCatalogs { 14 | create("libsx") { 15 | from(files("../versions/current.toml")) 16 | } 17 | } 18 | } 19 | 20 | rootProject.name = "JavaKotlinMavenInterop" 21 | include("kotlin-lib") 22 | include("java-app-gradle") 23 | -------------------------------------------------------------------------------- /MultiplatformDemo/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | */build 8 | /captures 9 | .externalNativeBuild 10 | .cxx 11 | local.properties 12 | ### CocoaPods ### 13 | ## CocoaPods GitIgnore Template 14 | 15 | # CocoaPods - Only use to conserve bandwidth / Save time on Pushing 16 | # - Also handy if you have a large number of dependant pods 17 | # - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE 18 | Pods/ 19 | 20 | ### Xcode ### 21 | # Xcode 22 | # 23 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 24 | 25 | ## User settings 26 | xcuserdata/ 27 | 28 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 29 | *.xcscmblueprint 30 | *.xccheckout 31 | 32 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 33 | build/ 34 | DerivedData/ 35 | *.moved-aside 36 | *.pbxuser 37 | !default.pbxuser 38 | *.mode1v3 39 | !default.mode1v3 40 | *.mode2v3 41 | !default.mode2v3 42 | *.perspectivev3 43 | !default.perspectivev3 44 | 45 | ## Gcc Patch 46 | /*.gcno 47 | 48 | ### Xcode Patch ### 49 | *.xcodeproj/* 50 | !*.xcodeproj/project.pbxproj 51 | !*.xcodeproj/xcshareddata/ 52 | !*.xcworkspace/contents.xcworkspacedata 53 | **/xcshareddata/WorkspaceSettings.xcsettings 54 | 55 | -------------------------------------------------------------------------------- /MultiplatformDemo/README.md: -------------------------------------------------------------------------------- 1 | ## Kotlin Multiplatform demo App using a shared business logic: 2 | 3 | The demo works on Android, iOS, macOS and JVM (currently Mac & Linux). 4 | 5 | 6 | 7 | ## Requirements 8 | 9 | - JDK 11 10 | - Android Studio [Dolphin (2021.3.1)](https://developer.android.com/studio) 11 | 12 | # Build and run for iOS 13 | 14 | ``` 15 | ./gradlew shared:podInstall 16 | cd iosApp 17 | pod install 18 | open iosApp.xcworkspace 19 | ``` 20 | 21 | # Build and run for macOS 22 | 23 | ``` 24 | ./gradlew shared:podInstall 25 | cd macosApp 26 | pod install 27 | open macosApp.xcworkspace 28 | ``` 29 | 30 | # Build and run for JVM 31 | 32 | ``` 33 | ./gradlew :jvmApp:run 34 | ``` 35 | 36 | # Build and run for Android 37 | 38 | ``` 39 | ./gradlew :androidApp:installDebug 40 | ``` 41 | -------------------------------------------------------------------------------- /MultiplatformDemo/Screenshots/Android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemo/Screenshots/Android.png -------------------------------------------------------------------------------- /MultiplatformDemo/Screenshots/JVM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemo/Screenshots/JVM.png -------------------------------------------------------------------------------- /MultiplatformDemo/Screenshots/Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemo/Screenshots/Overview.png -------------------------------------------------------------------------------- /MultiplatformDemo/Screenshots/iOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemo/Screenshots/iOS.png -------------------------------------------------------------------------------- /MultiplatformDemo/Screenshots/macOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemo/Screenshots/macOS.png -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.androidApplication) 3 | alias(libsx.plugins.kotlinAndroid) 4 | alias(libsx.plugins.compose.compiler) 5 | } 6 | 7 | dependencies { 8 | implementation(project(":shared")) 9 | implementation(libsx.androidx.compose) 10 | implementation(libsx.androidx.compose.ui) 11 | implementation(libsx.androidx.compose.material) 12 | } 13 | 14 | android { 15 | compileSdk = 34 16 | defaultConfig { 17 | namespace = "io.realm.kotlin.demo" 18 | applicationId = "io.realm.kotlin.demo" 19 | minSdk = 21 20 | targetSdk = 33 21 | versionCode = 1 22 | versionName = "1.0" 23 | } 24 | buildTypes { 25 | getByName("release") { 26 | isMinifyEnabled = true 27 | } 28 | } 29 | } 30 | tasks.withType { 31 | kotlinOptions.jvmTarget = libsx.versions.jvmTarget.get() 32 | } 33 | -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/Color.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.kotlin.demo.theme 18 | 19 | import androidx.compose.material.darkColors 20 | import androidx.compose.ui.graphics.Color 21 | 22 | val Purple200 = Color(0xFFBB86FC) 23 | val Purple500 = Color(0xFF6200EE) 24 | val Purple700 = Color(0xFF3700B3) 25 | val Teal200 = Color(0xFF03DAC5) 26 | 27 | val Green500 = Color(0xFF1EB980) 28 | val DarkBlue900 = Color(0xFF26282F) 29 | 30 | // Rally is always dark themed. 31 | val ColorPalette = darkColors( 32 | primary = Green500, 33 | surface = DarkBlue900, 34 | onSurface = Color.White, 35 | background = DarkBlue900, 36 | onBackground = Color.White 37 | ) 38 | -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/RealmColor.kt: -------------------------------------------------------------------------------- 1 | package io.realm.kotlin.demo.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | object RealmColor { 6 | // Grays 7 | val Charcoal = Color(0xFF1C233F) 8 | val Elephant = Color(0xFF9A9BA5) 9 | val ElephantHalf = Color(0xFFb1b3bf) 10 | val Dov = Color(0xFFEBEBF2) 11 | 12 | // Orb colors 13 | val Ultramarine = Color(0xFF39477F) 14 | val Indigo = Color(0xFF59569E) 15 | val GrapeJelly = Color(0xFF9A59A5) 16 | val Mulberry = Color(0xFFD34CA3) 17 | val Flamingo = Color(0xFFF25192) 18 | val SexySalmon = Color(0xFFF77C88) 19 | val Peach = Color(0xFFFC9F95) 20 | val Melon = Color(0xFFFCC397) 21 | } -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.kotlin.demo.theme 18 | 19 | import androidx.compose.foundation.shape.RoundedCornerShape 20 | import androidx.compose.material.Shapes 21 | import androidx.compose.ui.unit.dp 22 | 23 | val Shapes = Shapes( 24 | small = RoundedCornerShape(4.dp), 25 | medium = RoundedCornerShape(4.dp), 26 | large = RoundedCornerShape(0.dp) 27 | ) 28 | -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/Size.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.kotlin.demo.theme 18 | 19 | import androidx.compose.ui.unit.dp 20 | 21 | val rowSize = 60.dp 22 | -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /MultiplatformDemo/androidApp/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemo/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.kotlinMultiplatform) apply false 3 | alias(libsx.plugins.kotlinAndroid) apply false 4 | alias(libsx.plugins.kotlinJvm) apply false 5 | alias(libsx.plugins.androidApplication) apply false 6 | alias(libsx.plugins.androidLibrary) apply false 7 | alias(libsx.plugins.jetbrainsCompose) apply false 8 | alias(libsx.plugins.compose.compiler) apply false 9 | } 10 | 11 | // Explicitly adding the plugin to the classpath as it makes it easier to control the version 12 | // centrally (don't need version in the 'plugins' block). Further, snapshots are not published with 13 | // marker interface so would need to be added to the classpath manually anyway. 14 | buildscript { 15 | dependencies { 16 | classpath(libsx.realm.plugin) 17 | } 18 | } 19 | 20 | allprojects { 21 | group = "io.realm.sample" 22 | version = "1.0.0" 23 | } 24 | 25 | tasks.register("clean", Delete::class) { 26 | delete(rootProject.buildDir) 27 | } 28 | -------------------------------------------------------------------------------- /MultiplatformDemo/gradle.properties: -------------------------------------------------------------------------------- 1 | #Gradle 2 | org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" 3 | 4 | #Kotlin 5 | kotlin.code.style=official 6 | kotlin.mpp.stability.nowarn=true 7 | 8 | #Android 9 | android.useAndroidX=true -------------------------------------------------------------------------------- /MultiplatformDemo/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemo/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /MultiplatformDemo/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Sep 23 13:29:58 CEST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/Podfile: -------------------------------------------------------------------------------- 1 | target 'iosApp' do 2 | use_frameworks! 3 | platform :ios, '14.1' 4 | pod 'shared', :path => '../shared' 5 | end -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared" 10 | 11 | SPEC CHECKSUMS: 12 | shared: 492632fcf08a2d14a2b1d283dbe436da214cd3c3 13 | 14 | PODFILE CHECKSUM: f282da88f39e69507b0a255187c8a6b644477756 15 | 16 | COCOAPODS: 1.11.3 17 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp/Theme.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Theme.swift 3 | // iosApp 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | // Credit: https://stackoverflow.com/a/56874327/1389357 12 | extension Color { 13 | init(hex: UInt, alpha: Double = 1) { 14 | self.init( 15 | .sRGB, 16 | red: Double((hex >> 16) & 0xff) / 255, 17 | green: Double((hex >> 08) & 0xff) / 255, 18 | blue: Double((hex >> 00) & 0xff) / 255, 19 | opacity: alpha 20 | ) 21 | } 22 | } 23 | 24 | struct RealmColor { 25 | // Greys 26 | static let charcoal = Color.init(hex: 0x1C233F) 27 | static let elephant = Color.init(hex: 0x9A9BA5) 28 | static let dov = Color.init(hex: 0xEBEBF2) 29 | 30 | // Orb colors 31 | static let ultramarine = Color.init(hex: 0x39477F) 32 | static let indigo = Color.init(hex: 0x59569E) 33 | static let grapeJelly = Color.init(hex: 0x9A59A5) 34 | static let mulberry = Color.init(hex: 0xD34CA3) 35 | static let flamingo = Color.init(hex: 0xF25192) 36 | static let sexySalmon = Color.init(hex: 0xFC9F95) 37 | static let melon = Color.init(hex: 0xFCC397) 38 | } 39 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp/ViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModel.swift 3 | // iosApp 4 | // 5 | // Created by Christian Melchior on 24/09/2021. 6 | // 7 | import Foundation 8 | import Combine 9 | import shared 10 | 11 | // Generic Observable View Model, making it easier to control the lifecycle 12 | // of multiple Flows. 13 | class ObservableViewModel { 14 | private var jobs = Array() // List of Kotlin Coroutine Jobs 15 | 16 | func addObserver(observer: Closeable) { 17 | jobs.append(observer) 18 | } 19 | 20 | func stop() { 21 | jobs.forEach { job in job.close() } 22 | } 23 | } 24 | 25 | class IOSCounterViewModel: ObservableViewModel, ObservableObject { 26 | @Published var counter: String = "-" 27 | 28 | private let vm: SharedCounterViewModel = SharedCounterViewModel() 29 | 30 | func increment() { 31 | vm.increment() 32 | } 33 | 34 | func decrement() { 35 | vm.decrement() 36 | } 37 | 38 | func start() { 39 | addObserver(observer: vm.observeCounter().watch { counterValue in 40 | self.counter = counterValue! as String 41 | }) 42 | } 43 | 44 | override func stop() { 45 | super.stop() 46 | vm.close() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosApp/iOSApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // iOSApp.swift 3 | // iosApp 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct iOSApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosAppTests/iosAppTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // iosAppTests.swift 3 | // iosAppTests 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import XCTest 9 | @testable import iosApp 10 | 11 | class iosAppTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /MultiplatformDemo/iosApp/iosAppUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemo/jvmApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.kotlinJvm) 3 | alias(libsx.plugins.jetbrainsCompose) 4 | alias(libsx.plugins.compose.compiler) 5 | application 6 | } 7 | 8 | repositories { 9 | mavenCentral() 10 | google() 11 | maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev") 12 | maven("https://oss.sonatype.org/content/repositories/snapshots") 13 | } 14 | 15 | dependencies { 16 | implementation(compose.desktop.currentOs) 17 | implementation(project(":shared")) 18 | } 19 | 20 | application { 21 | mainClass.set("io.realm.kotlin.demo.MainKt") 22 | } 23 | -------------------------------------------------------------------------------- /MultiplatformDemo/jvmApp/src/main/kotlin/io/realm/kotlin/demo/theme/RealmColor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.theme 17 | 18 | import androidx.compose.ui.graphics.Color 19 | 20 | object RealmColor { 21 | // Grays 22 | val Charcoal = Color(0xFF1C233F) 23 | val Elephant = Color(0xFF9A9BA5) 24 | val Dov = Color(0xFFEBEBF2) 25 | 26 | // Orb colors 27 | val Ultramarine = Color(0xFF39477F) 28 | val Indigo = Color(0xFF59569E) 29 | val GrapeJelly = Color(0xFF9A59A5) 30 | val Mulberry = Color(0xFFD34CA3) 31 | val Flamingo = Color(0xFFF25192) 32 | val SexySalmon = Color(0xFFF77C88) 33 | val Peach = Color(0xFFFC9F95) 34 | val Melon = Color(0xFFFCC397) 35 | } -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/Podfile: -------------------------------------------------------------------------------- 1 | target 'macosApp' do 2 | use_frameworks! 3 | platform :osx, '11.1' 4 | pod 'shared', :path => '../shared' 5 | end -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared" 10 | 11 | SPEC CHECKSUMS: 12 | shared: 492632fcf08a2d14a2b1d283dbe436da214cd3c3 13 | 14 | PODFILE CHECKSUM: f3c0715e2cb2ef94e629cad90792d18c14dead0f 15 | 16 | COCOAPODS: 1.11.3 17 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSMinimumSystemVersion 22 | $(MACOSX_DEPLOYMENT_TARGET) 23 | 24 | 25 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/MacOSApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // macosAppApp.swift 3 | // macosApp 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct MacOSApp: App { 12 | let vm = MacOSCounterViewModel() 13 | var body: some Scene { 14 | WindowGroup(vm.platform(), id: "MainScreen") { 15 | ContentView(viewModel: vm) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/Theme.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Theme.swift 3 | // macosApp 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | // Credit: https://stackoverflow.com/a/56874327/1389357 12 | extension Color { 13 | init(hex: UInt, alpha: Double = 1) { 14 | self.init( 15 | .sRGB, 16 | red: Double((hex >> 16) & 0xff) / 255, 17 | green: Double((hex >> 08) & 0xff) / 255, 18 | blue: Double((hex >> 00) & 0xff) / 255, 19 | opacity: alpha 20 | ) 21 | } 22 | } 23 | 24 | struct RealmColor { 25 | // Greys 26 | static let charcoal = Color.init(hex: 0x1C233F) 27 | static let elephant = Color.init(hex: 0x9A9BA5) 28 | static let dov = Color.init(hex: 0xEBEBF2) 29 | 30 | // Orb colors 31 | static let ultramarine = Color.init(hex: 0x39477F) 32 | static let indigo = Color.init(hex: 0x59569E) 33 | static let grapeJelly = Color.init(hex: 0x9A59A5) 34 | static let mulberry = Color.init(hex: 0xD34CA3) 35 | static let flamingo = Color.init(hex: 0xF25192) 36 | static let sexySalmon = Color.init(hex: 0xFC9F95) 37 | static let melon = Color.init(hex: 0xFCC397) 38 | } 39 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/ViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewModel.swift 3 | // macosApp 4 | // 5 | // Created by Christian Melchior on 24/09/2021. 6 | // 7 | import Foundation 8 | import Combine 9 | import shared 10 | 11 | // Generic Observable View Model, making it easier to control the lifecycle 12 | // of multiple Flows. 13 | class ObservableViewModel { 14 | private var jobs = Array() // List of Kotlin Coroutine Jobs 15 | 16 | func addObserver(observer: Closeable) { 17 | jobs.append(observer) 18 | } 19 | 20 | func stop() { 21 | jobs.forEach { job in job.close() } 22 | } 23 | } 24 | 25 | class MacOSCounterViewModel: ObservableViewModel, ObservableObject { 26 | @Published var counter: String = "-" 27 | private let vm: SharedCounterViewModel = SharedCounterViewModel() 28 | 29 | func platform() -> String { 30 | return vm.platform 31 | } 32 | 33 | func increment() { 34 | vm.increment() 35 | } 36 | 37 | func decrement() { 38 | vm.decrement() 39 | } 40 | 41 | func start() { 42 | addObserver(observer: vm.observeCounter().watch { counterValue in 43 | self.counter = counterValue! as String 44 | }) 45 | } 46 | 47 | override func stop() { 48 | super.stop() 49 | vm.close() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosApp/macosApp.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosAppTests/macosAppTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // macosAppTests.swift 3 | // macosAppTests 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import XCTest 9 | @testable import macosApp 10 | 11 | class macosAppTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /MultiplatformDemo/macosApp/macosAppUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemo/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev") 7 | // Only required for realm-kotlin snapshots 8 | maven("https://oss.sonatype.org/content/repositories/snapshots") 9 | } 10 | } 11 | 12 | dependencyResolutionManagement { 13 | versionCatalogs { 14 | create("libsx") { 15 | from(files("../versions/current.toml")) 16 | } 17 | } 18 | repositories { 19 | google() 20 | mavenCentral() 21 | // Only required for realm-kotlin snapshots 22 | maven("https://oss.sonatype.org/content/repositories/snapshots") 23 | } 24 | } 25 | rootProject.name = "Realm Kotlin Multiplatform Demo" 26 | include(":androidApp") 27 | include(":jvmApp") 28 | include(":shared") 29 | -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/androidMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | actual class Platform actual constructor() { 19 | actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}" 20 | } -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/commonMain/kotlin/io/realm/kotlin/demo/model/entity/Counter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.model.entity 17 | 18 | import io.realm.kotlin.types.RealmList 19 | import io.realm.kotlin.types.RealmObject 20 | import io.realm.kotlin.types.annotations.PrimaryKey 21 | import io.realm.kotlin.ext.realmListOf 22 | 23 | class Counter: RealmObject { 24 | @PrimaryKey 25 | var id: String = "primary" 26 | var operations: RealmList = realmListOf() 27 | } 28 | -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/commonMain/kotlin/io/realm/kotlin/demo/ui/counter/CounterViewModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | import io.realm.kotlin.demo.ui.SharedViewModel 19 | import io.realm.kotlin.demo.util.CommonFlow 20 | 21 | /** 22 | * Interface describing the ViewModel on both the `shared` and `platform` side. 23 | */ 24 | interface CounterViewModel: SharedViewModel { 25 | val platform: String 26 | get() = Platform().platform 27 | fun observeCounter(): CommonFlow 28 | fun increment() 29 | fun decrement() 30 | } -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/commonMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | expect class Platform() { 19 | val platform: String 20 | } -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/commonMain/kotlin/io/realm/kotlin/demo/util/Closeable.kt: -------------------------------------------------------------------------------- 1 | package io.realm.kotlin.demo.util 2 | 3 | // Remove when Kotlin's Closeable is supported in K/N https://youtrack.jetbrains.com/issue/KT-31066 4 | // Alternatively use Ktor Closeable which is K/N ready. 5 | interface Closeable { 6 | fun close() 7 | } -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/commonMain/kotlin/io/realm/kotlin/demo/util/FlowUtil.kt: -------------------------------------------------------------------------------- 1 | package io.realm.kotlin.demo.util 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | import kotlinx.coroutines.Dispatchers 5 | import kotlinx.coroutines.Job 6 | import kotlinx.coroutines.flow.Flow 7 | import kotlinx.coroutines.flow.launchIn 8 | import kotlinx.coroutines.flow.onEach 9 | 10 | /** 11 | * Wrapper to consume Flow based API from Obj-C/Swift 12 | * Credit - https://github.com/JetBrains/kotlinconf-app/blob/master/common/src/mobileMain/kotlin/org/jetbrains/kotlinconf/FlowUtils.kt 13 | */ 14 | class CommonFlow(private val origin: Flow) : Flow by origin { 15 | fun watch(block: (T) -> Unit): Closeable { 16 | val job = Job() 17 | onEach { 18 | block(it) 19 | }.launchIn(CoroutineScope(Dispatchers.Main + job)) 20 | 21 | return object : Closeable { 22 | override fun close() { 23 | job.cancel() 24 | } 25 | } 26 | } 27 | } 28 | // Helper extension 29 | internal fun Flow.asCommonFlow(): CommonFlow = CommonFlow(this) 30 | -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/iosMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | import platform.UIKit.UIDevice 19 | 20 | actual class Platform actual constructor() { 21 | actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion 22 | } -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/jvmMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | actual class Platform actual constructor() { 19 | actual val platform: String = "JVM (${System.getProperty("os.name")})" 20 | } -------------------------------------------------------------------------------- /MultiplatformDemo/shared/src/macosMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | import platform.Foundation.NSProcessInfo 19 | 20 | actual class Platform actual constructor() { 21 | actual val platform: String = NSProcessInfo.processInfo.operatingSystemVersionString 22 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | */build 8 | /captures 9 | .externalNativeBuild 10 | .cxx 11 | local.properties 12 | ### CocoaPods ### 13 | ## CocoaPods GitIgnore Template 14 | 15 | # CocoaPods - Only use to conserve bandwidth / Save time on Pushing 16 | # - Also handy if you have a large number of dependant pods 17 | # - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE 18 | Pods/ 19 | 20 | ### Xcode ### 21 | # Xcode 22 | # 23 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 24 | 25 | ## User settings 26 | xcuserdata/ 27 | 28 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 29 | *.xcscmblueprint 30 | *.xccheckout 31 | 32 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 33 | build/ 34 | DerivedData/ 35 | *.moved-aside 36 | *.pbxuser 37 | !default.pbxuser 38 | *.mode1v3 39 | !default.mode1v3 40 | *.mode2v3 41 | !default.mode2v3 42 | *.perspectivev3 43 | !default.perspectivev3 44 | 45 | ## Gcc Patch 46 | /*.gcno 47 | 48 | ### Xcode Patch ### 49 | *.xcodeproj/* 50 | !*.xcodeproj/project.pbxproj 51 | !*.xcodeproj/xcshareddata/ 52 | !*.xcworkspace/contents.xcworkspacedata 53 | **/xcshareddata/WorkspaceSettings.xcsettings 54 | 55 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/Screenshots/kotlin-sync-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemoWithSync/Screenshots/kotlin-sync-demo.gif -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.androidApplication) 3 | alias(libsx.plugins.kotlinAndroid) 4 | alias(libsx.plugins.compose.compiler) 5 | } 6 | 7 | dependencies { 8 | implementation(project(":shared")) 9 | implementation(libsx.androidx.compose) 10 | implementation(libsx.androidx.compose.ui) 11 | implementation(libsx.androidx.compose.material) 12 | } 13 | 14 | android { 15 | compileSdk = 34 16 | defaultConfig { 17 | namespace = "io.realm.kotlin.demo" 18 | applicationId = "io.realm.kotlin.demo" 19 | minSdk = 21 20 | targetSdk = 33 21 | versionCode = 1 22 | versionName = "1.0" 23 | } 24 | buildTypes { 25 | getByName("release") { 26 | isMinifyEnabled = true 27 | } 28 | } 29 | } 30 | tasks.withType { 31 | kotlinOptions.jvmTarget = libsx.versions.jvmTarget.get() 32 | } 33 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/Color.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.kotlin.demo.theme 18 | 19 | import androidx.compose.material.darkColors 20 | import androidx.compose.ui.graphics.Color 21 | 22 | val Purple200 = Color(0xFFBB86FC) 23 | val Purple500 = Color(0xFF6200EE) 24 | val Purple700 = Color(0xFF3700B3) 25 | val Teal200 = Color(0xFF03DAC5) 26 | 27 | val Green500 = Color(0xFF1EB980) 28 | val DarkBlue900 = Color(0xFF26282F) 29 | 30 | // Rally is always dark themed. 31 | val ColorPalette = darkColors( 32 | primary = Green500, 33 | surface = DarkBlue900, 34 | onSurface = Color.White, 35 | background = DarkBlue900, 36 | onBackground = Color.White 37 | ) 38 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/RealmColor.kt: -------------------------------------------------------------------------------- 1 | package io.realm.kotlin.demo.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | object RealmColor { 6 | // Grays 7 | val Charcoal = Color(0xFF1C233F) 8 | val Elephant = Color(0xFF9A9BA5) 9 | val ElephantHalf = Color(0xFFb1b3bf) 10 | val Dov = Color(0xFFEBEBF2) 11 | 12 | // Orb colors 13 | val Ultramarine = Color(0xFF39477F) 14 | val Indigo = Color(0xFF59569E) 15 | val GrapeJelly = Color(0xFF9A59A5) 16 | val Mulberry = Color(0xFFD34CA3) 17 | val Flamingo = Color(0xFFF25192) 18 | val SexySalmon = Color(0xFFF77C88) 19 | val Peach = Color(0xFFFC9F95) 20 | val Melon = Color(0xFFFCC397) 21 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.kotlin.demo.theme 18 | 19 | import androidx.compose.foundation.shape.RoundedCornerShape 20 | import androidx.compose.material.Shapes 21 | import androidx.compose.ui.unit.dp 22 | 23 | val Shapes = Shapes( 24 | small = RoundedCornerShape(4.dp), 25 | medium = RoundedCornerShape(4.dp), 26 | large = RoundedCornerShape(0.dp) 27 | ) 28 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/kotlin/io/realm/kotlin/demo/theme/Size.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.realm.kotlin.demo.theme 18 | 19 | import androidx.compose.ui.unit.dp 20 | 21 | val rowSize = 60.dp 22 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/res/drawable/wifi.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/res/drawable/wifi_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/androidApp/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.kotlinMultiplatform) apply false 3 | alias(libsx.plugins.kotlinAndroid) apply false 4 | alias(libsx.plugins.kotlinJvm) apply false 5 | alias(libsx.plugins.androidApplication) apply false 6 | alias(libsx.plugins.androidLibrary) apply false 7 | alias(libsx.plugins.jetbrainsCompose) apply false 8 | alias(libsx.plugins.compose.compiler) apply false 9 | } 10 | 11 | // Explicitly adding the plugin to the classpath as it makes it easier to control the version 12 | // centrally (don't need version in the 'plugins' block). Further, snapshots are not published with 13 | // marker interface so would need to be added to the classpath manually anyway. 14 | buildscript { 15 | dependencies { 16 | classpath(libsx.realm.plugin) 17 | } 18 | } 19 | 20 | allprojects { 21 | group = "io.realm.sample" 22 | version = "1.0.0" 23 | } 24 | 25 | tasks.register("clean", Delete::class) { 26 | delete(rootProject.buildDir) 27 | } 28 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/gradle.properties: -------------------------------------------------------------------------------- 1 | #Gradle 2 | org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" 3 | 4 | #Kotlin 5 | kotlin.code.style=official 6 | kotlin.mpp.stability.nowarn=true 7 | 8 | #Android 9 | android.useAndroidX=true -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemoWithSync/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Sep 23 13:29:58 CEST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/Podfile: -------------------------------------------------------------------------------- 1 | target 'iosApp' do 2 | use_frameworks! 3 | platform :ios, '14.1' 4 | pod 'shared', :path => '../shared' 5 | end -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared" 10 | 11 | SPEC CHECKSUMS: 12 | shared: aefa02b035c81b69c587b6defc83f636ed42c2ad 13 | 14 | PODFILE CHECKSUM: f282da88f39e69507b0a255187c8a6b644477756 15 | 16 | COCOAPODS: 1.11.3 17 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/wifi.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "Image.png", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/wifi.imageset/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/wifi.imageset/Image.png -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/wifi_off.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "ic_wifi_off_black_48dp.png", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/wifi_off.imageset/ic_wifi_off_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemoWithSync/iosApp/iosApp/Assets.xcassets/wifi_off.imageset/ic_wifi_off_black_48dp.png -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/Theme.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Theme.swift 3 | // iosApp 4 | // 5 | 6 | import Foundation 7 | import SwiftUI 8 | 9 | // Credit: https://stackoverflow.com/a/56874327/1389357 10 | extension Color { 11 | init(hex: UInt, alpha: Double = 1) { 12 | self.init( 13 | .sRGB, 14 | red: Double((hex >> 16) & 0xff) / 255, 15 | green: Double((hex >> 08) & 0xff) / 255, 16 | blue: Double((hex >> 00) & 0xff) / 255, 17 | opacity: alpha 18 | ) 19 | } 20 | } 21 | 22 | struct RealmColor { 23 | // Greys 24 | static let charcoal = Color.init(hex: 0x1C233F) 25 | static let elephant = Color.init(hex: 0x9A9BA5) 26 | static let dov = Color.init(hex: 0xEBEBF2) 27 | 28 | // Orb colors 29 | static let ultramarine = Color.init(hex: 0x39477F) 30 | static let indigo = Color.init(hex: 0x59569E) 31 | static let grapeJelly = Color.init(hex: 0x9A59A5) 32 | static let mulberry = Color.init(hex: 0xD34CA3) 33 | static let flamingo = Color.init(hex: 0xF25192) 34 | static let sexySalmon = Color.init(hex: 0xFC9F95) 35 | static let melon = Color.init(hex: 0xFCC397) 36 | } 37 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosApp/iOSApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // iOSApp.swift 3 | // iosApp 4 | // 5 | 6 | import SwiftUI 7 | 8 | @main 9 | struct iOSApp: App { 10 | var body: some Scene { 11 | WindowGroup { 12 | ContentView() 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosAppTests/iosAppTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // iosAppTests.swift 3 | // iosAppTests 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import XCTest 9 | @testable import iosApp 10 | 11 | class iosAppTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/iosApp/iosAppUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/jvmApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libsx.plugins.kotlinJvm) 3 | alias(libsx.plugins.jetbrainsCompose) 4 | alias(libsx.plugins.compose.compiler) 5 | application 6 | } 7 | 8 | repositories { 9 | mavenCentral() 10 | google() 11 | maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev") 12 | maven("https://oss.sonatype.org/content/repositories/snapshots") 13 | } 14 | 15 | dependencies { 16 | implementation(compose.desktop.currentOs) 17 | implementation(project(":shared")) 18 | } 19 | 20 | application { 21 | mainClass.set("io.realm.kotlin.demo.MainKt") 22 | } 23 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/jvmApp/src/main/kotlin/io/realm/kotlin/demo/theme/RealmColor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.theme 17 | 18 | import androidx.compose.ui.graphics.Color 19 | 20 | object RealmColor { 21 | // Grays 22 | val Charcoal = Color(0xFF1C233F) 23 | val Elephant = Color(0xFF9A9BA5) 24 | val Dov = Color(0xFFEBEBF2) 25 | 26 | // Orb colors 27 | val Ultramarine = Color(0xFF39477F) 28 | val Indigo = Color(0xFF59569E) 29 | val GrapeJelly = Color(0xFF9A59A5) 30 | val Mulberry = Color(0xFFD34CA3) 31 | val Flamingo = Color(0xFFF25192) 32 | val SexySalmon = Color(0xFFF77C88) 33 | val Peach = Color(0xFFFC9F95) 34 | val Melon = Color(0xFFFCC397) 35 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/jvmApp/src/main/resources/wifi.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/jvmApp/src/main/resources/wifi_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/Podfile: -------------------------------------------------------------------------------- 1 | target 'macosApp' do 2 | use_frameworks! 3 | platform :osx, '11.1' 4 | pod 'shared', :path => '../shared' 5 | end -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - shared (1.0) 3 | 4 | DEPENDENCIES: 5 | - shared (from `../shared`) 6 | 7 | EXTERNAL SOURCES: 8 | shared: 9 | :path: "../shared" 10 | 11 | SPEC CHECKSUMS: 12 | shared: aefa02b035c81b69c587b6defc83f636ed42c2ad 13 | 14 | PODFILE CHECKSUM: f3c0715e2cb2ef94e629cad90792d18c14dead0f 15 | 16 | COCOAPODS: 1.11.3 17 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/wifi_off.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_wifi_off_black_48dp.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/wifi_off.imageset/ic_wifi_off_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/wifi_off.imageset/ic_wifi_off_black_48dp.png -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/wifi_on.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_wifi_black_48dp.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/wifi_on.imageset/ic_wifi_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realm/realm-kotlin-samples/1c083c44c7c615bc5b6cbe510438785ce62635d4/MultiplatformDemoWithSync/macosApp/macosApp/Assets.xcassets/wifi_on.imageset/ic_wifi_black_48dp.png -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSMinimumSystemVersion 22 | $(MACOSX_DEPLOYMENT_TARGET) 23 | 24 | 25 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/MacOSApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // macosAppApp.swift 3 | // macosApp 4 | // 5 | import SwiftUI 6 | 7 | @main 8 | struct MacOSApp: App { 9 | let vm = MacOSCounterViewModel() 10 | var body: some Scene { 11 | WindowGroup(vm.platform(), id: "MainScreen") { 12 | ContentView(viewModel: vm) 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/Theme.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Theme.swift 3 | // macosApp 4 | // 5 | import Foundation 6 | import SwiftUI 7 | 8 | // Credit: https://stackoverflow.com/a/56874327/1389357 9 | extension Color { 10 | init(hex: UInt, alpha: Double = 1) { 11 | self.init( 12 | .sRGB, 13 | red: Double((hex >> 16) & 0xff) / 255, 14 | green: Double((hex >> 08) & 0xff) / 255, 15 | blue: Double((hex >> 00) & 0xff) / 255, 16 | opacity: alpha 17 | ) 18 | } 19 | } 20 | 21 | struct RealmColor { 22 | // Greys 23 | static let charcoal = Color.init(hex: 0x1C233F) 24 | static let elephant = Color.init(hex: 0x9A9BA5) 25 | static let dov = Color.init(hex: 0xEBEBF2) 26 | 27 | // Orb colors 28 | static let ultramarine = Color.init(hex: 0x39477F) 29 | static let indigo = Color.init(hex: 0x59569E) 30 | static let grapeJelly = Color.init(hex: 0x9A59A5) 31 | static let mulberry = Color.init(hex: 0xD34CA3) 32 | static let flamingo = Color.init(hex: 0xF25192) 33 | static let sexySalmon = Color.init(hex: 0xFC9F95) 34 | static let melon = Color.init(hex: 0xFCC397) 35 | } 36 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosApp/macosApp.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosAppTests/macosAppTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // macosAppTests.swift 3 | // macosAppTests 4 | // 5 | // Created by Christian Melchior on 01/10/2021. 6 | // 7 | 8 | import XCTest 9 | @testable import macosApp 10 | 11 | class macosAppTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/macosApp/macosAppUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev") 7 | // Only required for realm-kotlin snapshots 8 | maven("https://oss.sonatype.org/content/repositories/snapshots") 9 | } 10 | } 11 | 12 | dependencyResolutionManagement { 13 | versionCatalogs { 14 | create("libsx") { 15 | from(files("../versions/current.toml")) 16 | } 17 | } 18 | repositories { 19 | google() 20 | mavenCentral() 21 | // Only required for realm-kotlin snapshots 22 | maven("https://oss.sonatype.org/content/repositories/snapshots") 23 | } 24 | } 25 | rootProject.name = "realm-kotlin-multiplatform-sync-demo" 26 | include(":androidApp") 27 | include(":jvmApp") 28 | include(":shared") 29 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/androidMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | actual class Platform actual constructor() { 19 | actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}" 20 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/commonMain/kotlin/io/realm/kotlin/demo/model/entity/Counter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.model.entity 17 | 18 | import io.realm.kotlin.types.MutableRealmInt 19 | import io.realm.kotlin.types.RealmObject 20 | import io.realm.kotlin.types.annotations.PrimaryKey 21 | 22 | class Counter(userId: String): RealmObject { 23 | 24 | // No-arg constructor required by Realm 25 | @Suppress("unused") 26 | constructor(): this("") 27 | 28 | @PrimaryKey 29 | var _id: String = userId 30 | var value: MutableRealmInt = MutableRealmInt.create(0) 31 | } 32 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/commonMain/kotlin/io/realm/kotlin/demo/ui/counter/CounterViewModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | import io.realm.kotlin.demo.ui.SharedViewModel 19 | import io.realm.kotlin.demo.util.CommonFlow 20 | import io.realm.kotlin.demo.util.CommonStateFlow 21 | 22 | /** 23 | * Interface describing the ViewModel on both the `shared` and `platform` side. 24 | */ 25 | interface CounterViewModel: SharedViewModel { 26 | val platform: String 27 | get() = Platform().platform 28 | fun observeCounter(): CommonFlow 29 | fun increment() 30 | fun decrement() 31 | fun observeWifiState(): CommonStateFlow 32 | fun enableWifi() 33 | fun disableWifi() 34 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/commonMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | expect class Platform() { 19 | val platform: String 20 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/commonMain/kotlin/io/realm/kotlin/demo/util/Closeable.kt: -------------------------------------------------------------------------------- 1 | package io.realm.kotlin.demo.util 2 | 3 | // Remove when Kotlin's Closeable is supported in K/N https://youtrack.jetbrains.com/issue/KT-31066 4 | // Alternatively use Ktor Closeable which is K/N ready. 5 | interface Closeable { 6 | fun close() 7 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/commonMain/kotlin/io/realm/kotlin/demo/util/Constants.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.util 17 | 18 | /** 19 | * Replace with your own App's credentials to enable Sync. 20 | * To setup the Realm Sync App on MongoDB Atlas follow the steps here 21 | * https://www.mongodb.com/docs/atlas/tutorial/create-atlas-account/ or watch the video tutorial https://www.youtube.com/watch?v=lqo0Yf7lnyg 22 | */ 23 | object Constants { 24 | val MONGODB_REALM_APP_ID = "[REPLACE ME]" 25 | val MONGODB_REALM_APP_USER = "[REPLACE ME]" 26 | val MONGODB_REALM_APP_PASSWORD = "[REPLACE ME]" 27 | } 28 | -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/iosMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | import platform.UIKit.UIDevice 19 | 20 | actual class Platform actual constructor() { 21 | actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion 22 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/jvmMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | actual class Platform actual constructor() { 19 | actual val platform: String = "JVM (${System.getProperty("os.name")})" 20 | } -------------------------------------------------------------------------------- /MultiplatformDemoWithSync/shared/src/macosMain/kotlin/io/realm/kotlin/demo/ui/counter/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Realm Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package io.realm.kotlin.demo.ui.counter 17 | 18 | import platform.Foundation.NSProcessInfo 19 | 20 | actual class Platform actual constructor() { 21 | actual val platform: String = NSProcessInfo.processInfo.operatingSystemVersionString 22 | } --------------------------------------------------------------------------------