{"id":371508,"date":"2024-05-21T04:50:29","date_gmt":"2024-05-21T04:50:29","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=371508"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=371508","title":{"rendered":"<span>ViewModel + Kotlin Multiplatform. \u041f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" width=\"760\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/id\/x2\/jf\/idx2jf4rojletkvgtsx0gfrccwy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/id\/x2\/jf\/idx2jf4rojletkvgtsx0gfrccwy.png\"\/><\/p>\n<p>  \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u0410\u043d\u043d\u0430 \u0416\u0430\u0440\u043a\u043e\u0432\u0430, \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Usetech. \u041a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Google \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u043e \u0441\u0432\u043e\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435 \u043a Koltin Multiplatform \u043d\u0430 \u043f\u0440\u043e\u0448\u043b\u043e\u043c Google I\/O 2023. \u0421\u043b\u0435\u0434\u043e\u043c \u0431\u044b\u043b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d \u0432\u0435\u043a\u0442\u043e\u0440 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a Jetpack \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 KMP. \u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u044b \u043d\u0430\u0437\u0430\u0434 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Google \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043b\u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0443\u044e \u043c\u043d\u043e\u0433\u0438\u043c\u0438 \u043d\u043e\u0432\u0438\u043d\u043a\u0443, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e ViewModels \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Lifecycle \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 API Kotlin Multiplatform. \u0418 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e, \u0447\u0442\u043e \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u043e, \u0430 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0441\u0432\u0435\u0436\u0438\u043c, \u0441 \u0447\u0435\u043c \u0436\u0435 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0434\u043e ViewModels \u0438\u0437 Lifecycle. <\/p>\n<p>  \u0421\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 ViewModel \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u044c \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 MVVM \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a \u043a\u0440\u043e\u0441\u0441-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c \u0438\u0434\u0435\u044f \u043d\u0435 \u043d\u043e\u0432\u0430\u044f. \u041c\u043d\u043e\u0433\u0438\u0435 \u0434\u0430\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u0441 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u043c\u0438.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0414\u043b\u044f KMP ViewModel \u2014 \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u044c \u043e\u0431\u0449\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b, \u043d\u043e \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043e\u0431\u0449\u0435\u0439 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e:<\/p>\n<pre><code class=\"kotlin\">open class ViewModel{     val job = SupervisorJob()     protected var scope: CoroutineScope = CoroutineScope(uiDispatcher + job) } <\/code><\/pre>\n<p>  \u0415\u0449\u0435 1.5 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u0438 \u0432 \u043e\u0431\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 KMP \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0430 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0445 \u0443\u0441\u0438\u043b\u0438\u0439, \u043e \u0447\u0435\u043c \u044f \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0441\u0430\u043b\u0430. \u0421\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u043c \u0434\u0430\u0436\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c expect\/actual \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u043e\u0432 \u043a\u043e\u0440\u0443\u0442\u0438\u043d. \u041f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0432 commonMain \u0432 \u0444\u0430\u0439\u043b\u0435:<\/p>\n<pre><code class=\"kotlin\">val ioDispatcher = Dispatchers.IO val uiDispatcher = Dispatchers.Main <\/code><\/pre>\n<p>  \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, expect\/actual \u043e\u0441\u0442\u0430\u043b\u0441\u044f, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0437\u0430 \u043d\u0430\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0449\u0438\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438. \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 iOS \u0438 Android \u0442\u0430\u0440\u0433\u0435\u0442\u043e\u0432 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u0430\u043a \u0431\u0430\u0437\u043e\u0432\u044b\u0439, \u0430 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u044b \u043a\u043e\u0440\u0443\u0442\u0438\u043d \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u0432\u043e\u0435\u0439 \u043b\u043e\u0433\u0438\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430:<\/p>\n<pre><code class=\"kotlin\">class NewsViewModel(private val useCase: NewsUseCase) : ViewModel() {     var newsFlow = MutableStateFlow&lt;NewsList?>(null)      fun loadNews() {         scope.launch {             val result = withContext(ioDispatcher) {                 useCase.invoke(Unit)             }             result.getOrNull()?.let {                 newsFlow.tryEmit(it)             }         }     } } <\/code><\/pre>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0442\u0430\u043a\u0443\u044e ViewModel \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 \u043d\u0430\u0448\u0438\u0445 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445:<\/p>\n<pre><code class=\"kotlin\">\/\/Android class NewsActivity : PreComposeActivity() {   val vm: NewsViewMode = NewsViewModel()      override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_news)        setContent {           NewsListScreen(viewModel = vm)        }     } }  \/\/IOS class NewsListModel : ObservableObject {  private lazy var vm: NewsViewModel? = {         let vm = NewsViewModel()         vm?.newsFlow.collect(collector: itemsCollector, completionHandler: {_ in})         return vm     }() <\/code><\/pre>\n<p>  \u0418\u043b\u0438 \u0432 DI-\u0440\u0435\u0448\u0435\u043d\u0438\u044f\u0445:  <\/p>\n<pre><code class=\"kotlin\">class KoinDI : KoinComponent { \/\/...     val vmModule = module {         factory&lt;NewsViewModel> { NewsViewModel(get()) }     }      fun start() = startKoin {         modules(listOf(vmModule))     } }  \/\/\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435  private val vm: NewsViewModel? = KoinDIFactory.resolve(NewsViewModel::class) <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u044d\u0442\u043e \u0442\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u0435\u0439\u0447\u0430\u0441. \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0442 Google. <br \/>  <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/lifecycle?s=09#2.8.0-alpha03\">developer.android.com\/jetpack\/androidx\/releases\/lifecycle?s=09#2.8.0-alpha03<\/a>. \u042d\u0442\u043e \u0440\u043e\u0432\u043d\u043e \u0442\u043e\u0442 \u0436\u0435 \u043f\u0430\u043a\u0435\u0442 androidx.lifecycle:lifecycle-*. <\/p>\n<p>  \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0435\u0431\u0435 \u0432\u0441\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0438\u0437 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0432 \u043f\u0430\u043a\u0435\u0442. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c, \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u0435\u043a\u0446\u0438\u044e dependencies. \u041f\u0440\u0435\u0434\u0432\u043a\u0443\u0448\u0430\u0435\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Gradle Sync. \u0418 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u2026 \u0446\u0435\u043b\u043e\u0435 \u043d\u0438\u0447\u0435\u0433\u043e, \u0432\u0435\u0440\u043d\u0435\u0435, \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438:<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e, \u043e\u0448\u0438\u0431\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"kotlin\">Execution failed for task ':shared:transformIosMainCInteropDependenciesMetadataForIde'. > Could not resolve all files for configuration ':shared:iosX64CompilationDependenciesMetadata'.    > Could not resolve androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03.      Required by:          project :shared          project :shared > androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0-alpha03          project :shared > androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0-alpha03 > androidx.lifecycle:lifecycle-viewmodel:2.8.0-alpha03 > androidx.lifecycle:lifecycle-viewmodel-iosx64:2.8.0-alpha03       > No matching variant of androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03 was found. The consumer was configured to find a library for use during 'kotlin-metadata', preferably optimized for non-jvm, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native', attribute 'org.jetbrains.kotlin.native.target' with value 'ios_x64' but:           - Variant 'androidxSourcesElements' capability androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03:               - Incompatible because this component declares documentation for use during 'androidx-multiplatform-docs' and the consumer needed a library for use during 'kotlin-metadata'               - Other compatible attributes:                   - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')                   - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'native')           - Variant 'libraryVersionMetadata' capability androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03:               - Incompatible because this component declares documentation for use during 'library-version-metadata' and the consumer needed a library for use during 'kotlin-metadata'               - Other compatible attributes:                   - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')                   - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'native')           - Variant 'metadataApiElements' capability androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03 declares a library for use during 'kotlin-metadata':               - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'               - Other compatible attributes:                   - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')           - Variant 'metadataSourcesElements' capability androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03:               - Incompatible because this component declares documentation for use during 'kotlin-runtime', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a library for use during 'kotlin-metadata', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'               - Other compatible attributes:                   - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')           - Variant 'releaseApiElements-published' capability androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03 declares a library for use during compile-time:               - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'               - Other compatible attributes:                   - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')           - Variant 'releaseRuntimeElements-published' capability androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03 declares a library for use during runtime:               - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'               - Other compatible attributes:                   - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')           - Variant 'releaseSourcesElements-published' capability androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha03 declares a component for use during runtime:               - Incompatible because this component declares documentation, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' and the consumer needed a library, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'               - Other compatible attributes:                   - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')    > Could not resolve org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3.      Required by:          project :shared > androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0-alpha03       > No matching variant of org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 was found. The consumer was configured to find a library for use during 'kotlin-metadata', preferably optimized for non-jvm, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native', attribute 'org.jetbrains.kotlin.native.target' with value 'ios_x64' but:           - Variant 'apiElements' capability org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 declares a library for use during compile-time, preferably optimized for standard JVMs:               - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'               - Other compatible attribute:                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')           - Variant 'runtimeElements' capability org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 declares a library for use during runtime, preferably optimized for standard JVMs:               - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'               - Other compatible attribute:                   - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_x64')<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u041c\u044b, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0440\u0430\u0437\u043c\u0430\u0445\u043d\u0443\u043b\u0438\u0441\u044c. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043f\u043e\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f JVM \u0438 Android. \u041f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e lifecycle-viewmodel:<\/p>\n<pre><code class=\"kotlin\">val commonMain by getting {             dependencies {                 val lifecycle_version = \"2.8.0-alpha03\"                 implementation(\"androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version\")             }         } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u0430\u0448\u0438\u0445 ViewModel:<\/p>\n<pre><code class=\"kotlin\">import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope  open class BaseViewModel : ViewModel(){     val scope = this.viewModelScope } <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0438 \u0432 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0439 ViewModel \u0434\u043b\u044f Android \u0438 JVM, \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 viewModelScope:<\/p>\n<pre><code class=\"kotlin\">public val ViewModel.viewModelScope: CoroutineScope     get() = viewModelScopeLock.withLock {         getCloseable(VIEW_MODEL_SCOPE_KEY)             ?: createViewModelScope().also { scope -> addCloseable(VIEW_MODEL_SCOPE_KEY, scope) }     }  private val viewModelScopeLock = Lock() <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u043f\u043e lock, viewModelScope \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d.<\/p>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f createViewModelScope() \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043a\u043e\u0443\u043f \u043a\u043e\u0440\u0443\u0442\u0438\u043d, \u043a\u0443\u0434\u0430 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f Dispatchers.Main:<\/p>\n<pre><code class=\"kotlin\">internal fun createViewModelScope(): CloseableCoroutineScope {     val dispatcher = try {         Dispatchers.Main.immediate     } catch (_: NotImplementedError) {         \/\/ In platforms where `Dispatchers.Main` is not available, Kotlin Multiplatform will throw         \/\/ a `NotImplementedError`. Since there's no direct functional alternative, we use         \/\/ `EmptyCoroutineContext` to ensure a `launch` will run in the same context as the caller.         EmptyCoroutineContext     }     return CloseableCoroutineScope(coroutineContext = dispatcher + SupervisorJob()) } <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441 \u0442\u0430\u0440\u0433\u0435\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Dispatchers.Main, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Linux, \u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <b>EmptyCoroutineContext<\/b>. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, viewModelScope \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c.<\/p>\n<p>  \u0415\u0449\u0435 \u043e\u0434\u043d\u043e \u043d\u043e\u0432\u0448\u0435\u0441\u0442\u0432\u043e API ViewModels, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c viewModelScope \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0441\u043a\u043e\u0443\u043f\u043e\u0432 \u043a\u0430\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 ViewModel:<\/p>\n<pre><code class=\"kotlin\">class MyViewModel(   \/\/ Make Dispatchers.Main the default, rather than Dispatchers.Main.immediate   viewModelScope: CoroutineScope = Dispatchers.Main + SupervisorJob() ) : ViewModel(viewModelScope) {   \/\/ Use viewModelScope as before, without any code changes }  \/\/ Allows overriding the viewModelScope in a test fun Test() = runTest {   val viewModel = MyViewModel(backgroundScope) } <\/code><\/pre>\n<p>  \u0427\u0442\u043e \u0436, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u043e\u0432 \u043a\u043e\u0440\u0443\u0442\u0438\u043d, \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e, \u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0441\u0442\u044c\u0441\u044f \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0437\u044f\u043b\u0438 \u043d\u0430\u0448 \u043a\u043e\u0434 \u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b\u0438 \u0435\u0433\u043e \u0432 \u043e\u0431\u0449\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443.<\/p>\n<p>  \u0417\u0430\u043c\u0435\u043d\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0432 \u0441\u0432\u043e\u0435\u0439 ViewModel \u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0447\u0435\u0440\u0435\u0437 viewModelScope:<\/p>\n<pre><code class=\"kotlin\">class NewsViewModel() : BaseViewModel() {     var newsFlow = MutableStateFlow&lt;NewsList?>(null)     private val newsService = DI.newsService      fun loadNews() {         viewModelScope.launch {           val result = withContext(ioDispatcher) {                 newsService.loadNews()             }             newsItems.tryEmit(result.getOrNull()?.articles.orEmpty())         }     } } <\/code><\/pre>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c. \u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>  <img decoding=\"async\" width=\"480\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/7k\/50\/bq\/7k50bqkmovfun9vvkpk2uyvwvja.png\" data-src=\"https:\/\/habrastorage.org\/webt\/7k\/50\/bq\/7k50bqkmovfun9vvkpk2uyvwvja.png\"\/><\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 API \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u043a\u0440\u043e\u0441\u0441-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f: ViewModelStore, <b>ViewModelStoreOwner <\/b>\u0438 <b>ViewModelProvider<\/b>. ViewModelProvider \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u043f\u043e \u0442\u0438\u043f\u0443 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a java.lang.Class, \u043d\u043e \u0438 kotlin.reflect.KClass. <b>ViewModelProvider.NewInstanceFactory<\/b> \u0438 <b>ViewModelProvider.AndroidViewModelFactory<\/b> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f Android \u0438 JVM, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0445 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0442\u0430\u0440\u0433\u0435\u0442\u0430\u0445 \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443: <b>UnsupportedOperationException<\/b>. <\/p>\n<p>  \u0414\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u0435-JVM \u0442\u0430\u0440\u0433\u0435\u0442\u043e\u0432 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0434\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <b>ViewModelProvider.Factory<\/b> \u0441 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u0430 create:<\/p>\n<pre><code class=\"kotlin\">class CustomFactory: ViewModelProvider.Factory {      override fun &lt;T : ViewModel> create(modelClass: KClass&lt;T>, extras: CreationExtras): T {         return super.create(modelClass, extras)     } } <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 ViewModel \u0447\u0435\u0440\u0435\u0437 DI \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0438\u0447\u0435\u0433\u043e. <\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0432 Compose Multiplatform, \u0442\u043e \u0432\u0441\u0435 \u0431\u0443\u0434\u0435\u0442 \u0435\u0449\u0435 \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p>  \u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u0438\u0442\u043e\u0433. \u041d\u0430\u043c \u0434\u0430\u043b\u0438 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 API, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043d\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e ViewModel. \u0412\u0441\u044e \u0440\u0443\u0442\u0438\u043d\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u043b\u0430\u044e\u0442 \u0437\u0430 \u043d\u0430\u0441. \u041d\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043a\u043e\u0443\u043f\u044b \u043d\u0430 \u0441\u0432\u043e\u0439 \u0432\u043a\u0443\u0441.<br \/>  KMP \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0441\u0435 \u0431\u043e\u043b\u0435\u0435 \u0438 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u043c.<\/p>\n<p>  \u041e\u0441\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u0432\u044f\u0437\u0438 \ud83d\ude42<\/p>\n<p>  <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/lifecycle?s=09#2.8.0-alpha03\">\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438<\/a><\/p>\n<p>  <a href=\"https:\/\/github.com\/anioutkazharkova\/kmp_news_sample\">\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438<\/a><\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/802111\/\"> https:\/\/habr.com\/ru\/articles\/802111\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" width=\"760\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/id\/x2\/jf\/idx2jf4rojletkvgtsx0gfrccwy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/id\/x2\/jf\/idx2jf4rojletkvgtsx0gfrccwy.png\"\/><\/p>\n<p>  \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u0410\u043d\u043d\u0430 \u0416\u0430\u0440\u043a\u043e\u0432\u0430, \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Usetech. \u041a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Google \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u043e \u0441\u0432\u043e\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435 \u043a Koltin Multiplatform \u043d\u0430 \u043f\u0440\u043e\u0448\u043b\u043e\u043c Google I\/O 2023. \u0421\u043b\u0435\u0434\u043e\u043c \u0431\u044b\u043b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d \u0432\u0435\u043a\u0442\u043e\u0440 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a Jetpack \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 KMP. \u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u044b \u043d\u0430\u0437\u0430\u0434 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Google \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043b\u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0443\u044e \u043c\u043d\u043e\u0433\u0438\u043c\u0438 \u043d\u043e\u0432\u0438\u043d\u043a\u0443, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e ViewModels \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Lifecycle \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 API Kotlin Multiplatform. \u0418 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e, \u0447\u0442\u043e \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u043e, \u0430 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0441\u0432\u0435\u0436\u0438\u043c, \u0441 \u0447\u0435\u043c \u0436\u0435 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0434\u043e ViewModels \u0438\u0437 Lifecycle. <\/p>\n<p>  \u0421\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 ViewModel \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u044c \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 MVVM \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a \u043a\u0440\u043e\u0441\u0441-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c \u0438\u0434\u0435\u044f \u043d\u0435 \u043d\u043e\u0432\u0430\u044f. \u041c\u043d\u043e\u0433\u0438\u0435 \u0434\u0430\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u0441 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u043c\u0438.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-371508","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371508","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=371508"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371508\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=371508"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=371508"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=371508"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}