Skip to content

Commit 2b8201f

Browse files
committed
Sveta's ideas including updating to KMP-NativeCoroutines v1
1 parent 600da37 commit 2b8201f

File tree

12 files changed

+210
-126
lines changed

12 files changed

+210
-126
lines changed

step4/androidApp/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ android {
1717
compose = true
1818
}
1919
composeOptions {
20-
kotlinCompilerExtensionVersion = "1.4.7"
20+
kotlinCompilerExtensionVersion = "1.4.8"
2121
}
2222
packaging {
2323
resources {

step4/androidApp/src/main/java/com/jetbrains/simplelogin/kotlinmultiplatformsandbox/MainActivity.kt

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,23 @@ import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
66
import androidx.activity.viewModels
7+
import androidx.compose.foundation.layout.Arrangement
8+
import androidx.compose.foundation.layout.PaddingValues
79
import androidx.compose.foundation.layout.fillMaxSize
810
import androidx.compose.foundation.lazy.LazyColumn
911
import androidx.compose.foundation.lazy.items
12+
import androidx.compose.material.Divider
1013
import androidx.compose.material.MaterialTheme
1114
import androidx.compose.material.Surface
1215
import androidx.compose.material.Text
16+
import androidx.compose.runtime.Composable
1317
import androidx.compose.ui.Modifier
18+
import androidx.compose.ui.tooling.preview.Preview
19+
import androidx.compose.ui.unit.dp
1420
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1521

1622
class MainActivity : ComponentActivity() {
17-
18-
private val viewModel: MainViewModel by viewModels()
23+
private val mainViewModel: MainViewModel by viewModels()
1924

2025
override fun onCreate(savedInstanceState: Bundle?) {
2126
super.onCreate(savedInstanceState)
@@ -25,18 +30,32 @@ class MainActivity : ComponentActivity() {
2530
modifier = Modifier.fillMaxSize(),
2631
color = MaterialTheme.colors.background
2732
) {
28-
val greetings = viewModel.greetingList.collectAsStateWithLifecycle()
29-
if (greetings.value.isEmpty()) {
30-
Text("Loading")
31-
} else {
32-
LazyColumn {
33-
items(greetings.value) {
34-
Text(it)
35-
}
36-
}
37-
}
33+
val greetings = mainViewModel.greetingList.collectAsStateWithLifecycle()
34+
GreetingView(phrases = greetings.value)
3835
}
3936
}
4037
}
4138
}
39+
}
40+
41+
@Composable
42+
fun GreetingView(phrases: List<String>) {
43+
LazyColumn(
44+
contentPadding = PaddingValues(20.dp),
45+
verticalArrangement = Arrangement.spacedBy(8.dp),
46+
) {
47+
items(phrases) { phrase ->
48+
Text(phrase)
49+
Divider()
50+
}
51+
}
52+
}
53+
54+
55+
@Preview
56+
@Composable
57+
fun DefaultPreview() {
58+
MyApplicationTheme {
59+
GreetingView(listOf("Hello, Android!"))
60+
}
4261
}
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
package com.jetbrains.simplelogin.kotlinmultiplatformsandbox
22

3-
import Greeting
43
import androidx.lifecycle.ViewModel
54
import androidx.lifecycle.viewModelScope
5+
import kotlinx.coroutines.flow.MutableStateFlow
66
import kotlinx.coroutines.flow.SharingStarted
77
import kotlinx.coroutines.flow.StateFlow
88
import kotlinx.coroutines.flow.stateIn
9+
import kotlinx.coroutines.flow.update
10+
import kotlinx.coroutines.launch
911

1012
class MainViewModel : ViewModel() {
13+
private val _greetingList = MutableStateFlow<List<String>>(listOf())
14+
val greetingList: StateFlow<List<String>> get() = _greetingList
1115

12-
val greetingList: StateFlow<List<String>> = Greeting().greet().stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
16+
init {
17+
viewModelScope.launch {
18+
Greeting().greet().collect { phrase ->
19+
_greetingList.update { list -> list + phrase }
20+
}
21+
}
22+
}
1323

1424
}

step4/build.gradle.kts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
plugins {
22
//trick: for the same plugin versions in all sub-modules
3-
id("com.android.application").version("8.0.2").apply(false)
4-
id("com.android.library").version("8.0.2").apply(false)
5-
kotlin("android").version("1.8.21").apply(false)
6-
kotlin("multiplatform").version("1.8.21").apply(false)
3+
id("com.android.application").version("8.1.0-rc01").apply(false)
4+
id("com.android.library").version("8.1.0-rc01").apply(false)
5+
kotlin("android").version("1.8.22").apply(false)
6+
kotlin("multiplatform").version("1.8.22").apply(false)
7+
kotlin("plugin.serialization").version("1.8.22").apply(false)
8+
id("com.google.devtools.ksp").version("1.8.22-1.0.11").apply(false)
9+
id("com.rickclephas.kmp.nativecoroutines").version("1.0.0-ALPHA-13").apply(false)
710
}
811

912
tasks.register("clean", Delete::class) {

step4/iosApp/iosApp.xcodeproj/project.pbxproj

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; };
1111
058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; };
1212
2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; };
13-
66CD08D82A5ED96100D66EFD /* KMPNativeCoroutinesAsync in Frameworks */ = {isa = PBXBuildFile; productRef = 66CD08D72A5ED96100D66EFD /* KMPNativeCoroutinesAsync */; };
14-
66CD08DA2A5ED96100D66EFD /* KMPNativeCoroutinesCore in Frameworks */ = {isa = PBXBuildFile; productRef = 66CD08D92A5ED96100D66EFD /* KMPNativeCoroutinesCore */; };
13+
66CD08E22A66C3F600D66EFD /* KMPNativeCoroutinesAsync in Frameworks */ = {isa = PBXBuildFile; productRef = 66CD08E12A66C3F600D66EFD /* KMPNativeCoroutinesAsync */; };
14+
66CD08E42A66C3F600D66EFD /* KMPNativeCoroutinesCore in Frameworks */ = {isa = PBXBuildFile; productRef = 66CD08E32A66C3F600D66EFD /* KMPNativeCoroutinesCore */; };
1515
7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; };
1616
/* End PBXBuildFile section */
1717

@@ -42,8 +42,8 @@
4242
isa = PBXFrameworksBuildPhase;
4343
buildActionMask = 2147483647;
4444
files = (
45-
66CD08DA2A5ED96100D66EFD /* KMPNativeCoroutinesCore in Frameworks */,
46-
66CD08D82A5ED96100D66EFD /* KMPNativeCoroutinesAsync in Frameworks */,
45+
66CD08E42A66C3F600D66EFD /* KMPNativeCoroutinesCore in Frameworks */,
46+
66CD08E22A66C3F600D66EFD /* KMPNativeCoroutinesAsync in Frameworks */,
4747
);
4848
runOnlyForDeploymentPostprocessing = 0;
4949
};
@@ -113,8 +113,8 @@
113113
);
114114
name = iosApp;
115115
packageProductDependencies = (
116-
66CD08D72A5ED96100D66EFD /* KMPNativeCoroutinesAsync */,
117-
66CD08D92A5ED96100D66EFD /* KMPNativeCoroutinesCore */,
116+
66CD08E12A66C3F600D66EFD /* KMPNativeCoroutinesAsync */,
117+
66CD08E32A66C3F600D66EFD /* KMPNativeCoroutinesCore */,
118118
);
119119
productName = iosApp;
120120
productReference = 7555FF7B242A565900829871 /* iosApp.app */;
@@ -145,7 +145,7 @@
145145
);
146146
mainGroup = 7555FF72242A565900829871;
147147
packageReferences = (
148-
66CD08D62A5ED96100D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */,
148+
66CD08E02A66C3F600D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */,
149149
);
150150
productRefGroup = 7555FF7C242A565900829871 /* Products */;
151151
projectDirPath = "";
@@ -397,25 +397,25 @@
397397
/* End XCConfigurationList section */
398398

399399
/* Begin XCRemoteSwiftPackageReference section */
400-
66CD08D62A5ED96100D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */ = {
400+
66CD08E02A66C3F600D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */ = {
401401
isa = XCRemoteSwiftPackageReference;
402402
repositoryURL = "https://github.com/rickclephas/KMP-NativeCoroutines.git";
403403
requirement = {
404-
kind = exactVersion;
405-
version = 0.13.2;
404+
branch = master;
405+
kind = branch;
406406
};
407407
};
408408
/* End XCRemoteSwiftPackageReference section */
409409

410410
/* Begin XCSwiftPackageProductDependency section */
411-
66CD08D72A5ED96100D66EFD /* KMPNativeCoroutinesAsync */ = {
411+
66CD08E12A66C3F600D66EFD /* KMPNativeCoroutinesAsync */ = {
412412
isa = XCSwiftPackageProductDependency;
413-
package = 66CD08D62A5ED96100D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */;
413+
package = 66CD08E02A66C3F600D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */;
414414
productName = KMPNativeCoroutinesAsync;
415415
};
416-
66CD08D92A5ED96100D66EFD /* KMPNativeCoroutinesCore */ = {
416+
66CD08E32A66C3F600D66EFD /* KMPNativeCoroutinesCore */ = {
417417
isa = XCSwiftPackageProductDependency;
418-
package = 66CD08D62A5ED96100D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */;
418+
package = 66CD08E02A66C3F600D66EFD /* XCRemoteSwiftPackageReference "KMP-NativeCoroutines" */;
419419
productName = KMPNativeCoroutinesCore;
420420
};
421421
/* End XCSwiftPackageProductDependency section */

step4/iosApp/iosApp.xcodeproj/xcuserdata/pamelahill.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,91 @@
77
<key>Rx (Playground) 1.xcscheme</key>
88
<dict>
99
<key>isShown</key>
10-
<false />
10+
<false/>
1111
<key>orderHint</key>
12-
<integer>1</integer>
12+
<integer>2</integer>
13+
</dict>
14+
<key>Rx (Playground) 10.xcscheme</key>
15+
<dict>
16+
<key>isShown</key>
17+
<false/>
18+
<key>orderHint</key>
19+
<integer>11</integer>
20+
</dict>
21+
<key>Rx (Playground) 11.xcscheme</key>
22+
<dict>
23+
<key>isShown</key>
24+
<false/>
25+
<key>orderHint</key>
26+
<integer>12</integer>
1327
</dict>
1428
<key>Rx (Playground) 2.xcscheme</key>
1529
<dict>
1630
<key>isShown</key>
17-
<false />
31+
<false/>
1832
<key>orderHint</key>
19-
<integer>2</integer>
33+
<integer>3</integer>
2034
</dict>
2135
<key>Rx (Playground) 3.xcscheme</key>
2236
<dict>
2337
<key>isShown</key>
24-
<false />
38+
<false/>
2539
<key>orderHint</key>
26-
<integer>3</integer>
40+
<integer>4</integer>
2741
</dict>
2842
<key>Rx (Playground) 4.xcscheme</key>
2943
<dict>
3044
<key>isShown</key>
31-
<false />
45+
<false/>
3246
<key>orderHint</key>
33-
<integer>4</integer>
47+
<integer>5</integer>
3448
</dict>
3549
<key>Rx (Playground) 5.xcscheme</key>
3650
<dict>
3751
<key>isShown</key>
38-
<false />
52+
<false/>
3953
<key>orderHint</key>
40-
<integer>5</integer>
54+
<integer>6</integer>
55+
</dict>
56+
<key>Rx (Playground) 6.xcscheme</key>
57+
<dict>
58+
<key>isShown</key>
59+
<false/>
60+
<key>orderHint</key>
61+
<integer>7</integer>
62+
</dict>
63+
<key>Rx (Playground) 7.xcscheme</key>
64+
<dict>
65+
<key>isShown</key>
66+
<false/>
67+
<key>orderHint</key>
68+
<integer>8</integer>
69+
</dict>
70+
<key>Rx (Playground) 8.xcscheme</key>
71+
<dict>
72+
<key>isShown</key>
73+
<false/>
74+
<key>orderHint</key>
75+
<integer>9</integer>
76+
</dict>
77+
<key>Rx (Playground) 9.xcscheme</key>
78+
<dict>
79+
<key>isShown</key>
80+
<false/>
81+
<key>orderHint</key>
82+
<integer>10</integer>
4183
</dict>
4284
<key>Rx (Playground).xcscheme</key>
4385
<dict>
4486
<key>isShown</key>
45-
<false />
87+
<false/>
4688
<key>orderHint</key>
47-
<integer>0</integer>
89+
<integer>1</integer>
4890
</dict>
4991
<key>iosApp.xcscheme</key>
5092
<dict>
5193
<key>orderHint</key>
52-
<integer>6</integer>
94+
<integer>0</integer>
5395
</dict>
5496
</dict>
5597
</dict>

step4/iosApp/iosApp/ContentView.swift

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,54 +7,44 @@ struct ContentView: View {
77
@ObservedObject private(set) var viewModel: ViewModel
88

99
var body: some View {
10-
NavigationView {
11-
listView()
12-
.onAppear{self.viewModel.startObserving()}
13-
}
14-
}
15-
16-
private func listView() -> AnyView {
17-
switch viewModel.greetings {
18-
case .loading:
19-
return AnyView(Text("Loading...").multilineTextAlignment(.center))
20-
case .result(let greetingMessages):
21-
return AnyView(VStack {
22-
List {
23-
ForEach(greetingMessages, id: \.self) { greeting in
24-
Text(greeting)
25-
}
26-
}
27-
})
28-
case .error(let description):
29-
return AnyView(Text(description).multilineTextAlignment(.center))
30-
}
10+
ListView(phrases: viewModel.greetings)
11+
.onAppear { self.viewModel.startObserving() }
3112
}
32-
3313
}
3414

3515
extension ContentView {
36-
enum LoadableMessages {
37-
case loading
38-
case result([String])
39-
case error(String)
40-
}
41-
4216
@MainActor
4317
class ViewModel: ObservableObject {
44-
@Published var greetings = LoadableMessages.loading
18+
@Published var greetings: Array<String> = []
4519

4620
func startObserving() {
4721
Task {
48-
do {
49-
let stream = asyncStream(for: Greeting().greetNative())
50-
for try await data in stream {
51-
self.greetings = .result(data)
52-
}
53-
} catch {
54-
print("Failed with error: \(error)")
55-
self.greetings = .error("Error")
56-
}
57-
}
22+
do {
23+
let sequence = asyncSequence(for: Greeting().greet())
24+
for try await phrase in sequence {
25+
self.greetings.append(phrase)
26+
}
27+
} catch {
28+
print("Failed with error: \(error)")
29+
}
30+
}
31+
}
32+
}
33+
}
34+
35+
struct ListView: View {
36+
let phrases: Array<String>
37+
38+
var body: some View {
39+
List(phrases, id: \.self) {
40+
Text($0)
5841
}
5942
}
6043
}
44+
45+
46+
struct ListView_Previews: PreviewProvider {
47+
static var previews: some View {
48+
ListView(phrases: ["Hello"])
49+
}
50+
}

0 commit comments

Comments
 (0)