{"id":334716,"date":"2022-06-19T21:00:16","date_gmt":"2022-06-19T21:00:16","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=334716"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=334716","title":{"rendered":"<span>\u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c gRPC-\u043a\u043b\u0438\u0435\u043d\u0442 \u0432\u00a0\u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0430\u00a0Kotlin Multiplatform Mobile<\/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-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u0437 \u041d\u043e\u0432\u043e\u0441\u0438\u0431\u0438\u0440\u0441\u043a\u0430.<\/p>\n<p>\u041d\u0430\u043c \u0434\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0444\u0438\u0447\u0438 \u0432 KMM-\u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445, \u0438 \u0432\u043e\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e\u0434\u0432\u0435\u0440\u043d\u0443\u043b\u0430\u0441\u044c \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u041d\u0430 \u043d\u0435\u0439, \u043f\u043e\u043c\u0438\u043c\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u0444\u0438\u0447\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0442\u044c \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0441\u0440\u0435\u0434\u0435 iOS-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u043e\u043d\u0443\u0441\u043e\u043c \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0441\u043e\u0431\u044b\u0439 \u0430\u043a\u0446\u0435\u043d\u0442 \u043d\u0430 \u044d\u0442\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/7a9\/12f\/a61\/7a912fa61dee3f55777f3ef3e6c92b05.jpg\" width=\"1080\" height=\"607\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7a9\/12f\/a61\/7a912fa61dee3f55777f3ef3e6c92b05.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<h3>\u0412 \u0447\u0435\u043c \u0441\u0443\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438<\/h3>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e \u0432 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u00a0REST\u00a0API \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043e\u0444\u043e\u0440\u043c\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <code>swagger<\/code>-\u0444\u0430\u0439\u043b\u0430\u0445. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u0435 \u043c\u044b \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/ktor.io\" rel=\"noopener noreferrer nofollow\"><u>Ktor<\/u><\/a> \u0438 <a href=\"https:\/\/github.com\/icerockdev\/moko-network\" rel=\"noopener noreferrer nofollow\"><u>\u043d\u0430\u0448\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 moko-network<\/u><\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/github.com\/icerockdev\/moko-network#usage\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u043b\u0430\u0433\u0438\u043d<\/u><\/a> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043f\u043e <code>Swagger<\/code>&#8216;\u0443. \u0412 \u043e\u0447\u0435\u043d\u044c \u0440\u0435\u0434\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>WebSockets<\/code> \u0438\u043b\u0438 <code>Sockets.IO<\/code>. \u042d\u0442\u043e \u0440\u0435\u0448\u0430\u043b\u043e\u0441\u044c \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435. \u041f\u043e\u0437\u0434\u043d\u0435\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e <a href=\"https:\/\/github.com\/icerockdev\/moko-socket-io\" rel=\"noopener noreferrer nofollow\"><u>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 moko-sockets-io<\/u><\/a>.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0431\u044b\u043b\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435: \u043f\u043e\u043c\u0438\u043c\u043e \u043d\u0430\u0431\u043e\u0440\u0430 <code>swagger<\/code>-\u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0439 API \u0431\u044b\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 <a href=\"https:\/\/grpc.io\/docs\/what-is-grpc\/introduction\" rel=\"noopener noreferrer nofollow\"><u>gRPC-\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438<\/u><\/a>, \u0438 \u043d\u0430\u043c \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u044b\u043c \u0438 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u043c \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0REST\u00a0API.<\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 gRPC \u0432 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439. \u041e\u043d \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0444\u0438\u0447\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0415\u0441\u043b\u0438 \u0432\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 gRPC-\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0438 \u0432\u044b \u0443\u0436\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442\u0435 \u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438 \u043e \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435, \u0442\u043e \u0448\u0430\u0433\u0438 2, 3 \u0438 4 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c.<\/p>\n<p>\u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e:<\/p>\n<ul>\n<li>\n<p>\u0443\u043c\u0435\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c kotlin-\u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 common-\u043a\u043e\u0434\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0443\u043c\u0435\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c kotlin-\u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432 common-\u043a\u043e\u0434\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043c\u0435\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u043b\u044f iOS \u0438 Android;<\/p>\n<\/li>\n<li>\n<p>\u0443\u043c\u0435\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c gRPC-\u043a\u043b\u0438\u0435\u043d\u0442 \u0438\u0437 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430: \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u0448\u043b\u0430\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 gRPC, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 KMM-\u0447\u0430\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043b\u0430\u0441\u044c,\u00a0\u2014 <a href=\"https:\/\/github.com\/square\/wire\" rel=\"noopener noreferrer nofollow\"><u>Wire<\/u><\/a> \u043e\u0442 \u043a\u043e\u043b\u043b\u0435\u0433 \u0438\u0437 Square. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0432\u0437\u044f\u043b\u0438 \u0435\u0435 \u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u0447\u0442\u043e \u043c\u044b \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e KMM-\u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0434\u043b\u044f gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0434\u043e\u043b\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u043d\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u0445 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. <a href=\"http:\/\/square.github.io\/wire\/wire_grpc\/#getting-started\" rel=\"noopener noreferrer nofollow\"><u>\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u0430<\/u><\/a> \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 gRPC.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/square\/wire\/tree\/master\/wire-library\/wire-grpc-client\/src\/jvmMain\/kotlin\/com\/squareup\/wire\" rel=\"noopener noreferrer nofollow\"><u>\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u043b\u044f Android<\/u><\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 OkHttp \u043e\u0442 \u044d\u0442\u043e\u0439 \u0436\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432. \u0412 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/square.github.io\/okhttp\/3.x\/okhttp\/okhttp3\/OkHttpClient.Builder.html#addInterceptor-okhttp3.Interceptor-\" rel=\"noopener noreferrer nofollow\"><u>OkHttpClient.Builder.addInterceptor<\/u><\/a>.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043d\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u043b\u044f iOS, \u0442\u043e\u043b\u044c\u043a\u043e <a href=\"https:\/\/github.com\/square\/wire\/blob\/master\/wire-library\/wire-grpc-client\/src\/nativeMain\/kotlin\/com\/squareup\/wire\/GrpcResponse.kt\" rel=\"noopener noreferrer nofollow\"><u>\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430\u043c\u0438<\/u><\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b iOS \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u043d\u0435\u0435: \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0435\u0448\u0430\u0442\u044c \u043d\u0430\u0434\u043e, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b Android \u0432\u0441\u0435 \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u043e.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u0443\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 Hello world, \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0441 \u043d\u0443\u043b\u0435\u0432\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u043d\u043e\u0432\u0443\u044e \u0444\u0438\u0447\u0443. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0443\u043f\u043e\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 iOS-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u044c\u043c\u0435\u043c <a href=\"https:\/\/github.com\/grpc\/grpc-go\/tree\/master\/examples\" rel=\"noopener noreferrer nofollow\"><u>\u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 gprc-go<\/u><\/a>. \u0412\u0441\u0435 \u0448\u0430\u0433\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/tree\/grpc-article-steps\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442\u0430\u043c\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/u><\/a>.<\/p>\n<h3>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c:<\/h3>\n<ul>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B31\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (\u0448\u0430\u0433 1)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B3%D0%B8234\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u0444\u0438\u0447\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 (\u0448\u0430\u0433\u0438 2, 3, 4)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B35\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 wire-\u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043a common-\u043a\u043e\u0434\u0443 (\u0448\u0430\u0433 5)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B36\" rel=\"noopener noreferrer nofollow\">\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043c\u043e\u0434\u0443\u043b\u044f \u0444\u0438\u0447\u0438 \u0438\u0437 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 (\u0448\u0430\u0433 6)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B3%D0%B878\" rel=\"noopener noreferrer nofollow\">\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u043b\u044f iOS (\u0448\u0430\u0433\u0438 7, 8)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B38\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e KMM-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442 (\u0448\u0430\u0433 8)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B39\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0438\u0447\u0438 (\u0448\u0430\u0433 9)<\/a>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432 Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B31\" id=\"\u0448\u0430\u04331\"><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a01. \u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u2014 \u0431\u0435\u0440\u0435\u043c <a href=\"https:\/\/github.com\/grpc\/grpc-go\/blob\/master\/examples\/README.md\" rel=\"noopener noreferrer nofollow\"><u>\u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/u><\/a> \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430:<\/p>\n<pre><code>```  $ go get google.golang.org\/grpc\/examples\/helloworld\/greeter_client  $ go get google.golang.org\/grpc\/examples\/helloworld\/greeter_server  ```<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430\u0445:<\/p>\n<pre><code>```  $ ~\/go\/bin\/greeter_server  2022\/02\/13 20:04:13 server listening at 127.0.0.1:50051  2022\/02\/13 20:04:20 Received: world  ```  ```  $ ~\/go\/bin\/greeter_client  2022\/02\/13 20:04:20 Greeting: Hello world  ```<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f. \u0417\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442, \u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c: \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0435\u043c\u0443 \u0431\u043b\u0438\u0436\u0435 \u043a \u043a\u043e\u043d\u0446\u0443 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B3%D0%B8234\" id=\"\u0448\u0430\u0433\u0438234\"><\/a><\/p>\n<h3>\u0428\u0430\u0433 2. \u0421\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 MPP-\u043f\u0440\u043e\u0435\u043a\u0442<\/h3>\n<p>\u041c\u044b \u0432 IceRock \u0443\u0436\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/github.com\/icerockdev\/moko-template\" rel=\"noopener noreferrer nofollow\"><u>\u0441\u0432\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d<\/u><\/a> \u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043d\u0435\u0433\u043e \u0436\u0435. \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u043e \u043d\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 GitHub, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u044e \u043f\u0430\u043f\u043a\u0443 \u0432 Android Studio \u0438\u043b\u0438 IDEA \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043e.<\/p>\n<p>\u0412 <code>mpp-library\/feature<\/code> \u0432\u0438\u0434\u0438\u043c \u0434\u0432\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438 \u2014 <code>config<\/code> \u0438 <code>list<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/26a\/305\/2cf\/26a3052cff612ec4a90182a58a3a3d63.png\" alt=\"\" title=\"\" width=\"846\" height=\"1308\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/26a\/305\/2cf\/26a3052cff612ec4a90182a58a3a3d63.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0415\u0449\u0435 \u0435\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u043b\u044f \u043d\u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0435 <code>domain<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dd0\/a6c\/f24\/dd0a6cf248327f053e1c5e5cad42f24d.png\" width=\"722\" height=\"804\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dd0\/a6c\/f24\/dd0a6cf248327f053e1c5e5cad42f24d.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0421\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0438\u0445 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 <code>mpp-library<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f01\/185\/152\/f01185152bb7b039db6af4915a32e271.png\" width=\"770\" height=\"562\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f01\/185\/152\/f01185152bb7b039db6af4915a32e271.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>\u0428\u0430\u0433\u00a03. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0444\u0438\u0447\u0438<\/h3>\n<p>\u0414\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c <code>config<\/code> \u0441 \u043d\u043e\u0432\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>grpcTest<\/code>. \u041f\u043e\u0447\u0438\u0441\u0442\u0438\u043c \u043e\u0442 \u043b\u043e\u0433\u0438\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0435\u043c \u0444\u0430\u0439\u043b\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/799\/280\/a2b\/799280a2b2280379ffb94a2875d940f1.png\" width=\"870\" height=\"686\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/799\/280\/a2b\/799280a2b2280379ffb94a2875d940f1.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/f4bc7e456e7461a7aaaddb5bba48ffb282ee947b\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<ul>\n<li>\n<p><code>\/model\/GrpcTestRepository.kt<\/code>\u00a0\u2014 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u043b\u044f \u0444\u0438\u0447\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <code>SharedFactory<\/code>:<\/p>\n<\/li>\n<\/ul>\n<pre><code>```  package org.example.library.feature.grpcTest.model  interface GrpcTestRepository {  }  ```<\/code><\/pre>\n<ul>\n<li>\n<p><code>\/presentation\/GrpcTestViewModel.kt<\/code> \u2014 \u043f\u0443\u0441\u0442\u0430\u044f \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c. \u041e\u043d\u0430 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 <code>dev.icerock.moko.mvvm.viewmodel.ViewModel<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043c\u0435\u0435\u0442 <code>coroutine scope<\/code> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432. \u0422\u0430\u043a\u0436\u0435 \u0432 \u043d\u0435\u0439 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043a\u0438\u0434\u0430\u0442\u044c \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (<code>eventsDispatcher<\/code>) \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:<\/p>\n<\/li>\n<\/ul>\n<pre><code>```  package org.example.library.feature.grpcTest.presentation  import dev.icerock.moko.mvvm.dispatcher.EventsDispatcher  import dev.icerock.moko.mvvm.dispatcher.EventsDispatcherOwner  import dev.icerock.moko.mvvm.viewmodel.ViewModel  import org.example.library.feature.grpcTest.model.GrpcTestRepository  class GrpcTestViewModel(  \u00a0\u00a0\u00a0override val eventsDispatcher: EventsDispatcher&lt;EventsListener>,  \u00a0\u00a0\u00a0private val repository: GrpcTestRepository  ) : ViewModel(), EventsDispatcherOwner&lt;GrpcTestViewModel.EventsListener> {  \u00a0\u00a0\u00a0interface EventsListener {  \u00a0\u00a0\u00a0}  }  ```<\/code><\/pre>\n<ul>\n<li>\n<p><code>\/di\/GrpcTestFactory.kt<\/code> \u2014 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u0444\u0438\u0447\u0438. \u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0444\u0430\u0431\u0440\u0438\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <code>SharedFactory<\/code>. \u0422\u0430\u043c \u0436\u0435 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f, \u043a\u0430\u043a\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f. \u041c\u0435\u0442\u043e\u0434\u044b \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b:<\/p>\n<\/li>\n<\/ul>\n<pre><code>```  package org.example.library.feature.grpcTest.di  import dev.icerock.moko.mvvm.dispatcher.EventsDispatcher  import org.example.library.feature.grpcTest.model.GrpcTestRepository  import org.example.library.feature.grpcTest.presentation.GrpcTestViewModel  class GrpcTestFactory(  \u00a0\u00a0private val repository: GrpcTestRepository  ) {  \u00a0\u00a0\u00a0\u00a0fun createViewModel(  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventsDispatcher: EventsDispatcher&lt;GrpcTestViewModel.EventsListener>,  \u00a0\u00a0\u00a0\u00a0) = GrpcTestViewModel(  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventsDispatcher = eventsDispatcher,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0repository = repository  \u00a0\u00a0\u00a0\u00a0)  }  ```<\/code><\/pre>\n<p><code>EventsDispatcher<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d <a href=\"https:\/\/github.com\/icerockdev\/moko-mvvm\/tree\/master\/mvvm-core\/src\/commonMain\/kotlin\/dev\/icerock\/moko\/mvvm\/dispatcher\" rel=\"noopener noreferrer nofollow\"><u>\u0437\u0434\u0435\u0441\u044c<\/u><\/a> \u0438 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443. \u0414\u043b\u044f iOS \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e <a href=\"https:\/\/github.com\/icerockdev\/moko-mvvm\/blob\/8af3cf1069313b01d7b694605e2da24d5667c5d9\/mvvm-core\/src\/iosMain\/kotlin\/dev\/icerock\/moko\/mvvm\/dispatcher\/EventsDispatcher.kt#L29\" rel=\"noopener noreferrer nofollow\"><u>\u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/u><\/a>. \u0414\u043b\u044f\u00a0Android \u2014 <a href=\"https:\/\/github.com\/icerockdev\/moko-mvvm\/blob\/8af3cf1069313b01d7b694605e2da24d5667c5d9\/mvvm-core\/src\/androidMain\/kotlin\/dev\/icerock\/moko\/mvvm\/dispatcher\/EventsDispatcher.kt#L19\" rel=\"noopener noreferrer nofollow\"><u>\u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430<\/u><\/a>.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0443\u0442\u044c \u0434\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0444\u0438\u0447\u0438 \u0432 <code>settings.gradle.kts<\/code> \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/b4ca49bdf28cd4f9e1fa99c98283a75bf92e6f21\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  include(\":mpp-library:feature:grpcTest\")  ```<\/code><\/pre>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c \u0444\u0438\u0447\u0438 \u043a \u043c\u043e\u0434\u0443\u043b\u044e <code>mpp-library<\/code> \u0432 <code>\/mpp-library\/build.gradle.kts<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/4d01b60c76cdf7af5a0ad74312dfa30ce1e1bd23\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  ...  dependencies {  ...  commonMainApi(projects.mppLibrary.feature.grpcTest) \/\/\u0427\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0444\u0438\u0447\u0438 \u0432 SharedFactory  ...  }  ...  framework {  \u00a0\u00a0...  \u00a0\u00a0export(projects.mppLibrary.feature.grpcTest)\u00a0 \/\/ \u0427\u0442\u043e\u0431\u044b \u043a\u043b\u0430\u0441\u0441\u044b \u0444\u0438\u0447\u0438 \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f iOS  \u00a0\u00a0...  }  ```<\/code><\/pre>\n<p>\u0418 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442 \u0432 <code>AndroidManifest.xml<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/0e4b36677a9c59af9aeb8c7b84d51f2adc80cdb2\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  &lt;?xml version=\"1.0\" encoding=\"utf-8\"?>  &lt;manifest package=\"org.example.library.feature.grpcTest\" \/>  ```<\/code><\/pre>\n<h3>\u0428\u0430\u0433\u00a04. \u041f\u0438\u0448\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0444\u0438\u0447\u0438<\/h3>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0443 \u043d\u0430\u0441 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435: \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u043e\u0442\u0432\u0435\u0442. \u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0435\u0433\u043e \u0432 <code>GrpcTestRepository<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/5b142204f7bd8a3e074bb973fc39c5fcb07d1993\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  interface GrpcTestRepository {  \u00a0\u00a0\u00a0\u00a0suspend fun helloRequest(word: String): String  }  ```<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0430\u043b\u0435\u0440\u0442\u0435 (\u0442\u0435\u043a\u0441\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0438) \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 <code>EventsListener<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/c0a5918efc8560388fec32ebd664ddc0214da95b\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  interface EventsListener {  \u00a0\u00a0\u00a0\u00a0fun showMessage(message: String)  }  ```<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0432 <code>GrpcTestViewModel<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044e. \u0417\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0439\u0434\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/7148f9af047c9e6c6d60ad0272f8b7b09a4df0db\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  fun onMainButtonTap() {  \u00a0\u00a0\u00a0\u00a0viewModelScope.launch {  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var message: String = \"\"  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0try {  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = repository.helloRequest(\"world\")  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} catch (exc: Exception) {  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = \"Error: \" + (exc.message ?: \"Unknown error\")  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventsDispatcher.dispatchEvent { showMessage(message) }  \u00a0\u00a0\u00a0\u00a0}  }  ```<\/code><\/pre>\n<p>\u041e\u0431\u0449\u0438\u0439 \u043a\u043e\u0434 \u043c\u043e\u0434\u0443\u043b\u044f \u0444\u0438\u0447\u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0433\u043e\u0442\u043e\u0432, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u0430 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e grpc-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043d\u0430\u0448\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B35\" id=\"\u0448\u0430\u04335\"><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a05. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u00a0proto-\u0444\u0430\u0439\u043b\u0430\u043c<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0435\u0440\u0435\u043c \u0444\u0430\u0439\u043b \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 <a href=\"https:\/\/github.com\/grpc\/grpc-go\/blob\/master\/examples\/helloworld\/helloworld\/helloworld.proto\" rel=\"noopener noreferrer nofollow\"><u>helloworld.proto<\/u><\/a> \u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 <code>\/domain\/src\/proto<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1b3\/5d0\/f20\/1b35d0f2000861b34e61d961d79feb0b.png\" width=\"806\" height=\"430\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1b3\/5d0\/f20\/1b35d0f2000861b34e61d961d79feb0b.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c wire-\u043f\u043b\u0430\u0433\u0438\u043d \u043a \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u043c\u0443 \u043c\u043e\u0434\u0443\u043b\u044e. \u0412\u0441\u0435 \u0448\u0430\u0433\u0438 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e <a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/253f609834e75e7dc1da21f15e12f9124f0297dd\" rel=\"noopener noreferrer nofollow\"><u>\u0441\u043e\u0431\u0440\u0430\u043d\u044b \u0432 \u043e\u0434\u0438\u043d \u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>libs.versions.toml<\/code> \u0434\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u0421 \u043d\u0435\u0433\u043e \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c:<\/p>\n<ol>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e <code>wire<\/code> \u0432 \u0441\u0435\u043a\u0446\u0438\u044e [versions]:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` # wire wireVersion = \"4.0.0-alpha.15\" ```<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043f\u043b\u0430\u0433\u0438\u043d \u0432 \u0441\u0435\u043a\u0446\u0438\u044e [libraries]:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` # wire wireGradle = { module = \"com.squareup.wire:wire-gradle-plugin\", version.ref = \"wireVersion\"} wireRuntime = { module = \"com.squareup.wire:wire-runtime\", version.ref = \"wireVersion\"} wireGrpcClient = { module = \"com.squareup.wire:wire-grpc-client\", version.ref = \"wireVersion\"} ``` <\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0446\u0435\u043f\u043b\u044f\u0435\u043c \u0441\u0430\u043c \u043f\u043b\u0430\u0433\u0438\u043d \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0432 <code>\/mpp-library\/domain\/build.gradle.kts<\/code>:<\/p>\n<ol start=\"3\">\n<li>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>Wire<\/code> \u0445\u043e\u0441\u0442\u0438\u0442\u0441\u044f \u043d\u0430 <code>jitpack.io<\/code>, \u0443\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043e\u0442\u0442\u0443\u0434\u0430 \u0432 <code>\/build-logic\/build.gradle.kts<\/code>:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` repositories {     mavenCentral()     google()      gradlePluginPortal()     maven(\"https:\/\/jitpack.io\") } ```<\/code><\/pre>\n<ol start=\"4\">\n<li>\n<p>\u0418 \u0437\u0434\u0435\u0441\u044c \u0436\u0435 \u0441\u0430\u043c \u043f\u043b\u0430\u0433\u0438\u043d \u0432 <code>dependencies<\/code>:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` dependencies {   ...   api(\"com.squareup.wire:wire-gradle-plugin:4.0.0-alpha.15\") } ```<\/code><\/pre>\n<ol start=\"5\">\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 domain-\u043c\u043e\u0434\u0443\u043b\u0435\u043c, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043b\u0430\u0433\u0438\u043d \u0432 \u0441\u0435\u043a\u0446\u0438\u044e <code>plugins<\/code> \u0432 <code>\/mpp-library\/domain\/build.gradle.kts<\/code>:<\/p>\n<\/li>\n<\/ol>\n<pre><code>```   ...   id(\"com.squareup.wire\") } ```<\/code><\/pre>\n<ol start=\"6\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u0435\u043a\u0446\u0438\u044e <code>dependencies<\/code> \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0430:<\/p>\n<\/li>\n<\/ol>\n<pre><code>```   ...   commonMainImplementation(libs.wireGrpcClient)   commonMainImplementation(libs.wireRuntime) }<\/code><\/pre>\n<ol start=\"7\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u043a\u0446\u0438\u044e <code>wire<\/code> \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0430\u0439\u043b\u0430 \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` wire {     sourcePath {       srcDir(\".\/src\/proto\")     }     kotlin {         rpcRole = \"client\"         rpcCallStyle = \"suspending\"     } } ```<\/code><\/pre>\n<ol start=\"8\">\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f gradle-\u0442\u0430\u0441\u043a\u0430 <code>generateProtos<\/code>:<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d0a\/65f\/dbb\/d0a65fdbba29ffa4d0e177d2df1dc23d.png\" width=\"680\" height=\"996\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d0a\/65f\/dbb\/d0a65fdbba29ffa4d0e177d2df1dc23d.png\"\/><figcaption><\/figcaption><\/figure>\n<ol start=\"9\">\n<li>\n<p>\u0418\u0442\u043e\u0433\u0438 \u0435\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 <code>\/mpp-library\/domain\/build\/generated\/source<\/code>:<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/95a\/2be\/580\/95a2be58066997845cbba9245136898d.png\" width=\"786\" height=\"486\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/95a\/2be\/580\/95a2be58066997845cbba9245136898d.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443 \u043d\u0430\u0441 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u044b\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (<code>HelloRequest<\/code>) \u0438 \u043e\u0442\u0432\u0435\u0442\u0430 (<code>HelloReply<\/code>) \u043c\u0435\u0442\u043e\u0434\u0430, \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (<code>GreeterClient<\/code>) \u0438 \u0435\u0433\u043e gRPC-\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f (<code>GrpcGreeterClient<\/code>).<\/p>\n<p>\u0417\u0430\u0431\u0435\u0433\u0430\u044f \u0432\u043f\u0435\u0440\u0435\u0434: \u043d\u0430 Android \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0441\u0435 \u044d\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u044b, \u043d\u0430 iOS \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0430\u0441\u0441\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B36\" id=\"\u0448\u0430\u04336\"><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a06. \u041e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c MPP-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f\u00a0gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/h3>\n<p>\u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0438 <code>HelloReply<\/code> \u0438 <code>HelloRequest<\/code> \u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0444\u0438\u0447\u0438 <code>GrpcTestRepository<\/code>. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0432 \u043e\u0431\u0449\u0435\u043c \u043a\u043e\u0434\u0435 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c, \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445.<\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>``` interface HelloWorldSuspendClient {     suspend fun sendHello(message: HelloRequest): HelloReply } ```<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f iOS \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441 suspend-\u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430 <code>callback<\/code>&#8216;\u0430\u0445:<\/p>\n<pre><code>``` interface HelloWorldCallbackClient {     fun sendHello(message: HelloRequest, callback: (HelloReply?, Exception?) -> Unit) } ```<\/code><\/pre>\n<p>\u0418 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044f\u0449\u0430\u044f \u043c\u0435\u0442\u043e\u0434\u044b \u0441 <code>callback<\/code>&#8216;\u0430\u043c\u0438 \u0432 <code>suspend<\/code>-\u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<pre><code>``` class HelloWorldSuspendClientImpl(     private val callbackClientCalls: HelloWorldCallbackClient ): HelloWorldSuspendClient {      \/\/\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434, \u043d\u043e \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f generic-\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438, \u0441\u0440\u0430\u0437\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0435     private suspend fun &lt;In, Out> convertCallbackCallToSuspend(         input: In,         callbackClosure: ((In, ((Out?, Throwable?) -> Unit)) -> Unit),     ): Out {         return suspendCoroutine { continuation ->             callbackClosure(input) { result, error ->                 when {                     error != null -> {                         continuation.resumeWith(Result.failure(error))                     }                     result != null -> {                         continuation.resumeWith(Result.success(result))                     }                     else -> { \/\/both values are null                         continuation.resumeWith(Result.failure(IllegalStateException(\"Incorrect grpc call processing\")))                     }                 }             }         }     }      override suspend fun sendHello(message: HelloRequest): HelloReply {         return convertCallbackCallToSuspend(message, callbackClosure = { input, callback ->             callbackClientCalls.sendHello(input, callback)         })     } } ```<\/code><\/pre>\n<p>\u0420\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u043c \u0432\u0441\u0435 \u044d\u0442\u043e \u0442\u0430\u043c \u0436\u0435, \u0433\u0434\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0438, \u0432 <code>domain<\/code>-\u043c\u043e\u0434\u0443\u043b\u0435 (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/c4b747644343b4455cf366b35847d8f1d3bf3257\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3da\/187\/7db\/3da1877dbbf258c952d146bf54c8c089.png\" width=\"824\" height=\"568\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3da\/187\/7db\/3da1877dbbf258c952d146bf54c8c089.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u043e\u0431\u0449\u0435\u043c \u043a\u043e\u0434\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u0432 <code>SharedFactory<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u0444\u0438\u0447\u0438.<\/p>\n<ol>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043a\u0430\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432 \u0444\u0430\u0431\u0440\u0438\u043a\u0443 \u0444\u0438\u0447\u0438 <code>GrpcTestFactory.kt<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/ea2738b4408b2e6f52d0ca028a309404bda4e5dd\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` class GrpcTestFactory(     private val repository: GrpcTestRepository ) {     fun createViewModel(         eventsDispatcher: EventsDispatcher&lt;GrpcTestViewModel.EventsListener>,     ) = GrpcTestViewModel(         eventsDispatcher = eventsDispatcher,         repository = repository     ) } ```<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b <code>SharedFactory<\/code> \u0438 \u0441\u0440\u0430\u0437\u0443 \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>suspend<\/code>-\u043e\u0431\u0435\u0440\u0442\u043a\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0430:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` class SharedFactory(     ...     helloWorldClient: HelloWorldSuspendClient ) {   \/\/\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b iOS-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u00ab\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u00bb constructor(     ...     helloWorldCallbackClient: HelloWorldCallbackClient ) : this(     ...     helloWorldClient = HelloWorldSuspendClientImpl(helloWorldCallbackClient) ) ... ```<\/code><\/pre>\n<ol start=\"3\">\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u044d\u0442\u043e\u0439 \u0444\u0430\u0431\u0440\u0438\u043a\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c gRPC-\u043a\u043b\u0438\u0435\u043d\u0442 \u043a\u0430\u043a \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/ee7ed3bd8b4e94a53d6664b269b9ce3680edecda\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` val grpcTestFactory = GrpcTestFactory(     repository = object : GrpcTestRepository {         override suspend fun helloRequest(word: String): String {             return helloWorldClient.sendHello(HelloRequest(word)).message         }     } ) ``` <\/code><\/pre>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u043a\u043e\u0434\u0435 \u0432\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c gRPC-\u043a\u043b\u0438\u0435\u043d\u0442 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B3%D0%B878\" id=\"\u0448\u0430\u0433\u043878\"><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a07. iOS: \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/h3>\n<p>\u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0432\u043e\u0437\u044c\u043c\u0435\u043c <a href=\"https:\/\/cocoapods.org\/pods\/gRPC-Swift\" rel=\"noopener noreferrer nofollow\"><u>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 gRPC-Swift<\/u><\/a>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0447\u0435\u0440\u0435\u0437 <code>Homebrew<\/code>:<\/p>\n<pre><code>``` brew install swift-protobuf grpc-swift ```<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u043a \u043d\u0435\u043c\u0443, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 cocoapods:<\/p>\n<pre><code>``` pod 'gRPC-Swift-Plugins' ```<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0442\u043e \u043e\u0431\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 <code>\/ios-app\/Pods\/gRPC-Swift-Plugins\/bin\/<\/code>, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ol>\n<li>\n<p>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>\/ios-app\/src\/generated\/proto<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0445\u043e\u0434\u044f\u0441\u044c \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` protoc \\ --plugin=.\/ios-app\/Pods\/gRPC-Swift-Plugins\/bin\/protoc-gen-swift \\ --swift_out=.\/ios-app\/src\/generated\/proto \\ --proto_path=.\/mpp-library\/domain\/src\/proto \\ .\/mpp-library\/domain\/src\/proto\/helloworld.proto ```<\/code><\/pre>\n<ol start=\"3\">\n<li>\n<p>\u041d\u0430\u0445\u043e\u0434\u044f\u0441\u044c \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` protoc \\ --plugin=.\/ios-app\/Pods\/gRPC-Swift-Plugins\/bin\/protoc-gen-grpc-swift \\ --grpc-swift_out=.\/ios-app\/src\/generated\/proto \\ --grpc-swift_opt=Client=true,Server=false \\ --proto_path=.\/mpp-library\/domain\/src\/proto \\ .\/mpp-library\/domain\/src\/proto\/helloworld.proto ```<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430: <code>helloworld.grpc.swift<\/code>, <code>helloworld.pb.swift<\/code>. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0432 <code>Podfile<\/code> \u0441\u0430\u043c\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <code>gRPC-Swift<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/59f94e452f6d0bc985d6296327e2dd79b558da52\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>``` pod 'gRPC-Swift', '~> 1.7.0' ```<\/code><\/pre>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B38\" id=\"\u0448\u0430\u04338\"><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a08. iOS: \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f HelloWorldClient<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 <code>HelloWorldCallbackClient<\/code>. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0435\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u0438\u0441\u044c gRPC-\u043a\u0430\u043d\u0430\u043b \u0438 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442:<\/p>\n<pre><code>``` class HelloWorldCallbackBridge: HelloWorldCallbackClient {      private var commonChannel: GRPCChannel?     private var helloClient: Helloworld_GreeterClient?      init() {          \/\/\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043b\u043e\u0433\u0433\u0435\u0440         var logger = Logger(label: \"gRPC\", factory: StreamLogHandler.standardOutput(label:))         logger.logLevel = .debug          \/\/loopCount \u2014 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0446\u0438\u043a\u043b\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u043d\u0430\u043b\u0430 (\u043c\u043e\u0433\u0443\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\/\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f)         let eventGroup = PlatformSupport.makeEventLoopGroup(loopCount: 4)          \/\/\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u0430\u043d\u0430\u043b, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u0438\u043f \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u0445\u043e\u0441\u0442 \u0438 \u043f\u043e\u0440\u0442         let newChannel = ClientConnection             \/\/\u041c\u043e\u0436\u043d\u043e \u0432\u043c\u0435\u0441\u0442\u043e .insecure \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c .usingTLS, \u043d\u043e \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0442\u0430\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442, \u0443 \u043d\u0435\u0433\u043e \u043d\u0435\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430             .insecure(group: eventGroup)             \/\/\u041b\u043e\u0433\u0433\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430             .withBackgroundActivityLogger(logger)             .connect(host: \"127.0.0.1\", port: 50051)          \/\/\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u043b\u043e\u0433\u0433\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u044b         let callOptions = CallOptions(             customMetadata: HPACKHeaders([]),             logger: logger         )          \/\/\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0430         helloClient = Helloworld_GreeterClient(             channel: newChannel,             defaultCallOptions: callOptions,             interceptors: nil         )         \/\/\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043a\u0430\u043d\u0430\u043b         commonChannel = newChannel     } ... ```<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <code>sayHello(..)<\/code>:<\/p>\n<pre><code>``` func sendHello(message: HelloRequest, callback: @escaping (HelloReply?, KotlinException?) -> Void) {     \/\/\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0447\u0442\u043e \u0432\u0441\u0435 \u0438\u0434\u0435\u0442 \u043f\u043e \u043f\u043b\u0430\u043d\u0443     guard let client = helloClient else {         callback(nil, nil)         return     }      \/\/\u0421\u043e\u0437\u0434\u0430\u0435\u043c SwiftProtobuf.Message \u0438\u0437 WireMessage     var request = Helloworld_HelloRequest()     request.name = message.name      \/\/\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0432\u044b\u0437\u043e\u0432\u0430     let responseCall = client.sayHello(request)     DispatchQueue.global().async {         do {             \/\/\u0412 \u0444\u043e\u043d\u0435 \u0434\u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u0437\u043e\u0432\u0430             let swiftMessage = try responseCall.response.wait()             DispatchQueue.main.async {                 \/\/\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c SwiftProtobuf.Message \u0432 WireMessage (\u043e\u0431\u044a\u0435\u043a\u0442 ADAPTER \u0443\u043c\u0435\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 WireMessage \u0438\u0437 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430)                 let (wireMessage, mappingError) = swiftMessage.toWireMessage(adapter: HelloReply.companion.ADAPTER)                 \/\/\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c callback \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0435 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u043b\u0441\u044f wireMessage, \u0438\u043d\u0430\u0447\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 KotlinNative-\u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435                 callback(wireMessage, mappingError)             }         } catch let err {             DispatchQueue.main.async {                 callback(nil, KotlinException(message: err.localizedDescription))             }         }     } } ```<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>toWireMessage(..)<\/code> \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u043e\u043d\u0430 \u0431\u0435\u0440\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>SwiftMessage<\/code> \u0432 \u0432\u0438\u0434\u0435 NSData, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0432 KotlinByteArray \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0443:<\/p>\n<pre><code>``` fileprivate extension SwiftProtobuf.Message {     func toWireMessage&lt;WireMessage, Adapter: Wire_runtimeProtoAdapter&lt;WireMessage>>(adapter: Adapter) -> (WireMessage?, KotlinException?) {         do {             let data = try self.serializedData()             let result = adapter.decode(bytes: data.toKotlinByteArray())              if let nResult = result {                 return (nResult, nil)             } else {                 return (nil, KotlinException(message: \"Cannot parse message data\"))             }         } catch let err {             return (nil, KotlinException(message: err.localizedDescription))         }     } } ```<\/code><\/pre>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 NSData \u0432 KotlinByteArray:<\/p>\n<pre><code>\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 NSData \u0432 KotlinByteArray: ``` fileprivate extension Data {     \/\/\u041f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u043e \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c NSData \u0432 KotlinByteArray     func toKotlinByteArray() -> KotlinByteArray {         let nsData = NSData(data: self)          return KotlinByteArray(size: Int32(self.count)) { index -> KotlinByte in             let byte = nsData.bytes.load(fromByteOffset: Int(truncating: index), as: Int8.self)             return KotlinByte(value: byte)         }     } } ```<\/code><\/pre>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432\u0441\u0435 \u0438 \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0432 <code>AppDelegate<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/fca9f02ee0083fc4bbed357aedeb436e655500f5\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>``` @UIApplicationMain class AppDelegate: NSObject, UIApplicationDelegate {      var window: UIWindow?      let gRPCClient = HelloWorldCallbackBridge()      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {          let request = HelloRequest(name: \"AppDelegate\", unknownFields: OkioByteString.companion.EMPTY)         gRPCClient.sendHello(message: request) { reply, error in             print(\"Reply: \\(reply?.message) - Error: \\(error?.message)\")         }         return true     } } ```<\/code><\/pre>\n<p>\u0412 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0435 \u0441 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<pre><code>``` 2022\/02\/17 23:51:28 Received: AppDelegate ```<\/code><\/pre>\n<p>\u0410 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u043c \u0432\u044b\u0432\u043e\u0434\u0435 XCode \u2014 \u043c\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u043e\u0432 \u043f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043a\u0430\u043d\u0430\u043b\u0430 \u0438 \u043d\u0430\u0448 <code>print<\/code>:<\/p>\n<pre><code>```  2022-02-17T23:51:27+0700 debug gRPC : old_state=idle grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 new_state=connecting connectivity state change  2022-02-17T23:51:27+0700 debug gRPC : grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 connectivity_state=connecting vending multiplexer future  2022-02-17T23:51:27+0700 debug gRPC : grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 making client bootstrap with event loop group of type NIOTSEventLoop  2022-02-17T23:51:27+0700 debug gRPC : grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 Network.framework is available and the EventLoopGroup is compatible with NIOTS, creating a NIOTSConnectionBootstrap  2022-02-17 23:51:28.487194+0700 mokoApp[34306:38235189] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed  2022-02-17T23:51:28+0700 debug gRPC : connectivity_state=connecting grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 activating connection  2022-02-17T23:51:28+0700 debug gRPC : h2_settings_max_frame_size=16384 grpc.conn.addr_remote=127.0.0.1 grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 grpc.conn.addr_local=127.0.0.1 HTTP2 settings update  2022-02-17T23:51:28+0700 debug gRPC : connectivity_state=active grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 connection ready  2022-02-17T23:51:28+0700 debug gRPC : grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 old_state=connecting new_state=ready connectivity state change  2022-02-17T23:51:28+0700 debug gRPC : grpc.conn.addr_remote=127.0.0.1 grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 grpc_request_id=682A7FB4-4543-4609-A2C0-498B8A1445A3 grpc.conn.addr_local=127.0.0.1 activated stream channel  2022-02-17T23:51:28+0700 debug gRPC : grpc.conn.addr_local=127.0.0.1 grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 grpc.conn.addr_remote=127.0.0.1 h2_stream_id=HTTP2StreamID(1) h2_active_streams=1 HTTP2 stream created  2022-02-17T23:51:28+0700 debug gRPC : h2_active_streams=0 grpc.conn.addr_remote=127.0.0.1 grpc.conn.addr_local=127.0.0.1 grpc_connection_id=7E6AA2F6-3F83-4448-BEB1-F0C3C85131AD\/0 h2_stream_id=HTTP2StreamID(1) HTTP2 stream closed  Reply: Optional(\"Hello AppDelegate\") - Error: nil  ```<\/code><\/pre>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B39\" id=\"\u0448\u0430\u04339\"><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a09. iOS: \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0438\u0447\u0438<\/h3>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430\u00a0<code>ConfigViewController<\/code>, \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0435 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0430\u043b\u0435\u0440\u0442 \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044e \u0438\u0437 <code>EventsListener<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/e95249cf0292fd64907e6693355e71e7b0d2d070\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>``` override func viewDidLoad() {   ...   grpcTestViewModel = AppComponent.factory.grpcTestFactory.createViewModel(eventsDispatcher: EventsDispatcher(listener: self))   }  override func viewDidAppear(_ animated: Bool) {     super.viewDidAppear(animated)     grpcTestViewModel.onMainButtonTap() }  deinit {     \/\/\u041e\u0447\u0438\u0449\u0430\u0435\u043c \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b     viewModel.onCleared()     grpcTestViewModel.onCleared() } ...  extension ConfigViewController: GrpcTestViewModelEventsListener {     func showMessage(message: String) {         let alert = UIAlertController(title: \"gRPC test\", message: message, preferredStyle: .alert)         present(alert, animated: true, completion: nil)     } } ```<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6f3\/d04\/6d8\/6f3d046d83bdf8cd0376ab5a18ef6a46.png\" width=\"820\" height=\"1438\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6f3\/d04\/6d8\/6f3d046d83bdf8cd0376ab5a18ef6a46.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f\u00a0Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>\u0421 \u0441\u0442\u043e\u0440\u043e\u043d\u044b Android-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 Wire-\u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0434\u0430\u0432 \u0435\u043c\u0443 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<ul>\n<li>\n<p>CommonMain-\u043a\u043e\u0434:<\/p>\n<\/li>\n<\/ul>\n<pre><code>``` class WireClientWrapper(grpcClient: GrpcClient): HelloWorldSuspendClient {     private val greeterClient = GrpcGreeterClient(grpcClient)     override suspend fun sendHello(message: HelloRequest): HelloReply {         return greeterClient.SayHello().execute(message)     } } ```<\/code><\/pre>\n<ul>\n<li>\n<p>AndroidMain-\u043a\u043e\u0434:<\/p>\n<\/li>\n<\/ul>\n<pre><code>``` val grpcOkhttpClient = OkHttpClient().newBuilder()     .protocols(listOf(okhttp3.Protocol.HTTP_2, okhttp3.Protocol.HTTP_1_1))     .build()  val grpcClient = GrpcClient.Builder()     .client(grpcOkhttpClient)     .baseUrl(\"127.0.0.1:50051\")     .build()  val helloClient = WireClientWrapper(grpcClient)  return SharedFactory(            settings = settings,            antilog = antilog,            newsUnitsFactory = newsUnitFactory,            baseUrl = BuildConfig.BASE_URL,            helloWorldClient = helloClient         ) ```<\/code><\/pre>\n<h3>\u0418\u0442\u043e\u0433\u0438<\/h3>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0432 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u0435\u0449\u0435 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c:<\/p>\n<ol>\n<li>\n<p>\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u043e\u043b\u0433\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f NSData \u0432 KotlinByteArray \u043d\u0430 <a href=\"https:\/\/github.com\/JetBrains\/kotlin-native\/issues\/3172#issuecomment-510051810\" rel=\"noopener noreferrer nofollow\"><u>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 memcpy<\/u><\/a>.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u043d\u0430\u043b \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u043f\u0440\u0438 \u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 <code>WireMessage<\/code> \u0432 <code>SwiftMessage<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u0430 \u0438 \u0441\u0430\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u0435\u0449\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0438 \u0434\u043e\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c. \u041d\u0430\u0434\u0435\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0446\u0435\u043b\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u0430, \u0438 \u0432\u0441\u0435\u043c \u043e\u0441\u0438\u043b\u0438\u0432\u0448\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043d\u0430 KMM \u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u044b\u043c\u0438 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u0432 \u043d\u0435\u0439.<\/p>\n<p>\u0414\u043e \u043d\u043e\u0432\u044b\u0445 \u0432\u0441\u0442\u0440\u0435\u0447!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/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\/post\/672278\/\"> https:\/\/habr.com\/ru\/post\/672278\/<\/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-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u0437 \u041d\u043e\u0432\u043e\u0441\u0438\u0431\u0438\u0440\u0441\u043a\u0430.<\/p>\n<p>\u041d\u0430\u043c \u0434\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0444\u0438\u0447\u0438 \u0432 KMM-\u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445, \u0438 \u0432\u043e\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e\u0434\u0432\u0435\u0440\u043d\u0443\u043b\u0430\u0441\u044c \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u041d\u0430 \u043d\u0435\u0439, \u043f\u043e\u043c\u0438\u043c\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u0444\u0438\u0447\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0442\u044c \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0441\u0440\u0435\u0434\u0435 iOS-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u043e\u043d\u0443\u0441\u043e\u043c \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0441\u043e\u0431\u044b\u0439 \u0430\u043a\u0446\u0435\u043d\u0442 \u043d\u0430 \u044d\u0442\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h3>\u0412 \u0447\u0435\u043c \u0441\u0443\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438<\/h3>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e \u0432 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u00a0REST\u00a0API \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043e\u0444\u043e\u0440\u043c\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <code>swagger<\/code>-\u0444\u0430\u0439\u043b\u0430\u0445. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u0435 \u043c\u044b \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/ktor.io\" rel=\"noopener noreferrer nofollow\"><u>Ktor<\/u><\/a> \u0438 <a href=\"https:\/\/github.com\/icerockdev\/moko-network\" rel=\"noopener noreferrer nofollow\"><u>\u043d\u0430\u0448\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 moko-network<\/u><\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/github.com\/icerockdev\/moko-network#usage\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u043b\u0430\u0433\u0438\u043d<\/u><\/a> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043f\u043e <code>Swagger<\/code>&#8216;\u0443. \u0412 \u043e\u0447\u0435\u043d\u044c \u0440\u0435\u0434\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>WebSockets<\/code> \u0438\u043b\u0438 <code>Sockets.IO<\/code>. \u042d\u0442\u043e \u0440\u0435\u0448\u0430\u043b\u043e\u0441\u044c \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435. \u041f\u043e\u0437\u0434\u043d\u0435\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e <a href=\"https:\/\/github.com\/icerockdev\/moko-socket-io\" rel=\"noopener noreferrer nofollow\"><u>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 moko-sockets-io<\/u><\/a>.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0431\u044b\u043b\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435: \u043f\u043e\u043c\u0438\u043c\u043e \u043d\u0430\u0431\u043e\u0440\u0430 <code>swagger<\/code>-\u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0439 API \u0431\u044b\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 <a href=\"https:\/\/grpc.io\/docs\/what-is-grpc\/introduction\" rel=\"noopener noreferrer nofollow\"><u>gRPC-\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438<\/u><\/a>, \u0438 \u043d\u0430\u043c \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u044b\u043c \u0438 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u043c \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u00a0REST\u00a0API.<\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 gRPC \u0432 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439. \u041e\u043d \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0444\u0438\u0447\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0415\u0441\u043b\u0438 \u0432\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 gRPC-\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0438 \u0432\u044b \u0443\u0436\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442\u0435 \u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438 \u043e \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435, \u0442\u043e \u0448\u0430\u0433\u0438 2, 3 \u0438 4 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c.<\/p>\n<p>\u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e:<\/p>\n<ul>\n<li>\n<p>\u0443\u043c\u0435\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c kotlin-\u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 common-\u043a\u043e\u0434\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0443\u043c\u0435\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c kotlin-\u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432 common-\u043a\u043e\u0434\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0438\u043c\u0435\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u043b\u044f iOS \u0438 Android;<\/p>\n<\/li>\n<li>\n<p>\u0443\u043c\u0435\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c gRPC-\u043a\u043b\u0438\u0435\u043d\u0442 \u0438\u0437 \u043e\u0431\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430: \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u0448\u043b\u0430\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 gRPC, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 KMM-\u0447\u0430\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043b\u0430\u0441\u044c,\u00a0\u2014 <a href=\"https:\/\/github.com\/square\/wire\" rel=\"noopener noreferrer nofollow\"><u>Wire<\/u><\/a> \u043e\u0442 \u043a\u043e\u043b\u043b\u0435\u0433 \u0438\u0437 Square. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0432\u0437\u044f\u043b\u0438 \u0435\u0435 \u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u0447\u0442\u043e \u043c\u044b \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e KMM-\u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u0434\u043b\u044f gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0434\u043e\u043b\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u043d\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u0445 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. <a href=\"http:\/\/square.github.io\/wire\/wire_grpc\/#getting-started\" rel=\"noopener noreferrer nofollow\"><u>\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u0430<\/u><\/a> \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 gRPC.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/square\/wire\/tree\/master\/wire-library\/wire-grpc-client\/src\/jvmMain\/kotlin\/com\/squareup\/wire\" rel=\"noopener noreferrer nofollow\"><u>\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u043b\u044f Android<\/u><\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 OkHttp \u043e\u0442 \u044d\u0442\u043e\u0439 \u0436\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432. \u0412 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/square.github.io\/okhttp\/3.x\/okhttp\/okhttp3\/OkHttpClient.Builder.html#addInterceptor-okhttp3.Interceptor-\" rel=\"noopener noreferrer nofollow\"><u>OkHttpClient.Builder.addInterceptor<\/u><\/a>.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043d\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u043b\u044f iOS, \u0442\u043e\u043b\u044c\u043a\u043e <a href=\"https:\/\/github.com\/square\/wire\/blob\/master\/wire-library\/wire-grpc-client\/src\/nativeMain\/kotlin\/com\/squareup\/wire\/GrpcResponse.kt\" rel=\"noopener noreferrer nofollow\"><u>\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430\u043c\u0438<\/u><\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b iOS \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u043d\u0435\u0435: \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0435\u0448\u0430\u0442\u044c \u043d\u0430\u0434\u043e, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b Android \u0432\u0441\u0435 \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u043e.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u0443\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 Hello world, \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0441 \u043d\u0443\u043b\u0435\u0432\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u043d\u043e\u0432\u0443\u044e \u0444\u0438\u0447\u0443. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0443\u043f\u043e\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 iOS-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u044c\u043c\u0435\u043c <a href=\"https:\/\/github.com\/grpc\/grpc-go\/tree\/master\/examples\" rel=\"noopener noreferrer nofollow\"><u>\u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 gprc-go<\/u><\/a>. \u0412\u0441\u0435 \u0448\u0430\u0433\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/tree\/grpc-article-steps\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442\u0430\u043c\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/u><\/a>.<\/p>\n<h3>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c:<\/h3>\n<ul>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B31\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (\u0448\u0430\u0433 1)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B3%D0%B8234\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u0444\u0438\u0447\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 (\u0448\u0430\u0433\u0438 2, 3, 4)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B35\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 wire-\u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043a common-\u043a\u043e\u0434\u0443 (\u0448\u0430\u0433 5)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B36\" rel=\"noopener noreferrer nofollow\">\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043c\u043e\u0434\u0443\u043b\u044f \u0444\u0438\u0447\u0438 \u0438\u0437 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 (\u0448\u0430\u0433 6)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B3%D0%B878\" rel=\"noopener noreferrer nofollow\">\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u043b\u044f iOS (\u0448\u0430\u0433\u0438 7, 8)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B38\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e KMM-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 gRPC-\u043a\u043b\u0438\u0435\u043d\u0442 (\u0448\u0430\u0433 8)<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%88%D0%B0%D0%B39\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b gRPC-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0438\u0447\u0438 (\u0448\u0430\u0433 9)<\/a>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432 Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B31\" id=\"\u0448\u0430\u04331\">1&#8243;><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a01. \u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u2014 \u0431\u0435\u0440\u0435\u043c <a href=\"https:\/\/github.com\/grpc\/grpc-go\/blob\/master\/examples\/README.md\" rel=\"noopener noreferrer nofollow\"><u>\u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/u><\/a> \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430:<\/p>\n<pre><code>```  $ go get google.golang.org\/grpc\/examples\/helloworld\/greeter_client  $ go get google.golang.org\/grpc\/examples\/helloworld\/greeter_server  ```<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430\u0445:<\/p>\n<pre><code>```  $ ~\/go\/bin\/greeter_server  2022\/02\/13 20:04:13 server listening at 127.0.0.1:50051  2022\/02\/13 20:04:20 Received: world  ```  ```  $ ~\/go\/bin\/greeter_client  2022\/02\/13 20:04:20 Greeting: Hello world  ```<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f. \u0417\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442, \u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c: \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0435\u043c\u0443 \u0431\u043b\u0438\u0436\u0435 \u043a \u043a\u043e\u043d\u0446\u0443 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B3%D0%B8234\" id=\"\u0448\u0430\u0433\u0438234\">34&#8243;><\/a><\/p>\n<h3>\u0428\u0430\u0433 2. \u0421\u0442\u0430\u0440\u0442\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 MPP-\u043f\u0440\u043e\u0435\u043a\u0442<\/h3>\n<p>\u041c\u044b \u0432 IceRock \u0443\u0436\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0430\u0432\u043d\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/github.com\/icerockdev\/moko-template\" rel=\"noopener noreferrer nofollow\"><u>\u0441\u0432\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d<\/u><\/a> \u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043d\u0435\u0433\u043e \u0436\u0435. \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u043e \u043d\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 GitHub, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u044e \u043f\u0430\u043f\u043a\u0443 \u0432 Android Studio \u0438\u043b\u0438 IDEA \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043e.<\/p>\n<p>\u0412 <code>mpp-library\/feature<\/code> \u0432\u0438\u0434\u0438\u043c \u0434\u0432\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438 \u2014 <code>config<\/code> \u0438 <code>list<\/code>:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0415\u0449\u0435 \u0435\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u043b\u044f \u043d\u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0435 <code>domain<\/code>:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0421\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0438\u0445 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 <code>mpp-library<\/code>:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h3>\u0428\u0430\u0433\u00a03. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0444\u0438\u0447\u0438<\/h3>\n<p>\u0414\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c <code>config<\/code> \u0441 \u043d\u043e\u0432\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>grpcTest<\/code>. \u041f\u043e\u0447\u0438\u0441\u0442\u0438\u043c \u043e\u0442 \u043b\u043e\u0433\u0438\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0435\u043c \u0444\u0430\u0439\u043b\u044b:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/f4bc7e456e7461a7aaaddb5bba48ffb282ee947b\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<ul>\n<li>\n<p><code>\/model\/GrpcTestRepository.kt<\/code>\u00a0\u2014 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u043b\u044f \u0444\u0438\u0447\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <code>SharedFactory<\/code>:<\/p>\n<\/li>\n<\/ul>\n<pre><code>```  package org.example.library.feature.grpcTest.model  interface GrpcTestRepository {  }  ```<\/code><\/pre>\n<ul>\n<li>\n<p><code>\/presentation\/GrpcTestViewModel.kt<\/code> \u2014 \u043f\u0443\u0441\u0442\u0430\u044f \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c. \u041e\u043d\u0430 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 <code>dev.icerock.moko.mvvm.viewmodel.ViewModel<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043c\u0435\u0435\u0442 <code>coroutine scope<\/code> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432. \u0422\u0430\u043a\u0436\u0435 \u0432 \u043d\u0435\u0439 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043a\u0438\u0434\u0430\u0442\u044c \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u044d\u0442\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (<code>eventsDispatcher<\/code>) \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:<\/p>\n<\/li>\n<\/ul>\n<pre><code>```  package org.example.library.feature.grpcTest.presentation  import dev.icerock.moko.mvvm.dispatcher.EventsDispatcher  import dev.icerock.moko.mvvm.dispatcher.EventsDispatcherOwner  import dev.icerock.moko.mvvm.viewmodel.ViewModel  import org.example.library.feature.grpcTest.model.GrpcTestRepository  class GrpcTestViewModel(  \u00a0\u00a0\u00a0override val eventsDispatcher: EventsDispatcher&lt;EventsListener>,  \u00a0\u00a0\u00a0private val repository: GrpcTestRepository  ) : ViewModel(), EventsDispatcherOwner&lt;GrpcTestViewModel.EventsListener> {  \u00a0\u00a0\u00a0interface EventsListener {  \u00a0\u00a0\u00a0}  }  ```<\/code><\/pre>\n<ul>\n<li>\n<p><code>\/di\/GrpcTestFactory.kt<\/code> \u2014 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u0444\u0438\u0447\u0438. \u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0444\u0430\u0431\u0440\u0438\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <code>SharedFactory<\/code>. \u0422\u0430\u043c \u0436\u0435 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f, \u043a\u0430\u043a\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f. \u041c\u0435\u0442\u043e\u0434\u044b \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b:<\/p>\n<\/li>\n<\/ul>\n<pre><code>```  package org.example.library.feature.grpcTest.di  import dev.icerock.moko.mvvm.dispatcher.EventsDispatcher  import org.example.library.feature.grpcTest.model.GrpcTestRepository  import org.example.library.feature.grpcTest.presentation.GrpcTestViewModel  class GrpcTestFactory(  \u00a0\u00a0private val repository: GrpcTestRepository  ) {  \u00a0\u00a0\u00a0\u00a0fun createViewModel(  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventsDispatcher: EventsDispatcher&lt;GrpcTestViewModel.EventsListener>,  \u00a0\u00a0\u00a0\u00a0) = GrpcTestViewModel(  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventsDispatcher = eventsDispatcher,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0repository = repository  \u00a0\u00a0\u00a0\u00a0)  }  ```<\/code><\/pre>\n<p><code>EventsDispatcher<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d <a href=\"https:\/\/github.com\/icerockdev\/moko-mvvm\/tree\/master\/mvvm-core\/src\/commonMain\/kotlin\/dev\/icerock\/moko\/mvvm\/dispatcher\" rel=\"noopener noreferrer nofollow\"><u>\u0437\u0434\u0435\u0441\u044c<\/u><\/a> \u0438 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443. \u0414\u043b\u044f iOS \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e <a href=\"https:\/\/github.com\/icerockdev\/moko-mvvm\/blob\/8af3cf1069313b01d7b694605e2da24d5667c5d9\/mvvm-core\/src\/iosMain\/kotlin\/dev\/icerock\/moko\/mvvm\/dispatcher\/EventsDispatcher.kt#L29\" rel=\"noopener noreferrer nofollow\"><u>\u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/u><\/a>. \u0414\u043b\u044f\u00a0Android \u2014 <a href=\"https:\/\/github.com\/icerockdev\/moko-mvvm\/blob\/8af3cf1069313b01d7b694605e2da24d5667c5d9\/mvvm-core\/src\/androidMain\/kotlin\/dev\/icerock\/moko\/mvvm\/dispatcher\/EventsDispatcher.kt#L19\" rel=\"noopener noreferrer nofollow\"><u>\u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430<\/u><\/a>.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0443\u0442\u044c \u0434\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0444\u0438\u0447\u0438 \u0432 <code>settings.gradle.kts<\/code> \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/b4ca49bdf28cd4f9e1fa99c98283a75bf92e6f21\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  include(\":mpp-library:feature:grpcTest\")  ```<\/code><\/pre>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c \u0444\u0438\u0447\u0438 \u043a \u043c\u043e\u0434\u0443\u043b\u044e <code>mpp-library<\/code> \u0432 <code>\/mpp-library\/build.gradle.kts<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/4d01b60c76cdf7af5a0ad74312dfa30ce1e1bd23\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  ...  dependencies {  ...  commonMainApi(projects.mppLibrary.feature.grpcTest) \/\/\u0427\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0444\u0438\u0447\u0438 \u0432 SharedFactory  ...  }  ...  framework {  \u00a0\u00a0...  \u00a0\u00a0export(projects.mppLibrary.feature.grpcTest)\u00a0 \/\/ \u0427\u0442\u043e\u0431\u044b \u043a\u043b\u0430\u0441\u0441\u044b \u0444\u0438\u0447\u0438 \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f iOS  \u00a0\u00a0...  }  ```<\/code><\/pre>\n<p>\u0418 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442 \u0432 <code>AndroidManifest.xml<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/0e4b36677a9c59af9aeb8c7b84d51f2adc80cdb2\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  &lt;?xml version=\"1.0\" encoding=\"utf-8\"?>  &lt;manifest package=\"org.example.library.feature.grpcTest\" \/>  ```<\/code><\/pre>\n<h3>\u0428\u0430\u0433\u00a04. \u041f\u0438\u0448\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0444\u0438\u0447\u0438<\/h3>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0443 \u043d\u0430\u0441 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435: \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u043e\u0442\u0432\u0435\u0442. \u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0435\u0433\u043e \u0432 <code>GrpcTestRepository<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/5b142204f7bd8a3e074bb973fc39c5fcb07d1993\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  interface GrpcTestRepository {  \u00a0\u00a0\u00a0\u00a0suspend fun helloRequest(word: String): String  }  ```<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0430\u043b\u0435\u0440\u0442\u0435 (\u0442\u0435\u043a\u0441\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0438) \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 <code>EventsListener<\/code> (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/c0a5918efc8560388fec32ebd664ddc0214da95b\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  interface EventsListener {  \u00a0\u00a0\u00a0\u00a0fun showMessage(message: String)  }  ```<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0432 <code>GrpcTestViewModel<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044e. \u0417\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0439\u0434\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a (<a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/7148f9af047c9e6c6d60ad0272f8b7b09a4df0db\" rel=\"noopener noreferrer nofollow\"><u>\u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>):<\/p>\n<pre><code>```  fun onMainButtonTap() {  \u00a0\u00a0\u00a0\u00a0viewModelScope.launch {  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var message: String = \"\"  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0try {  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = repository.helloRequest(\"world\")  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} catch (exc: Exception) {  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = \"Error: \" + (exc.message ?: \"Unknown error\")  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eventsDispatcher.dispatchEvent { showMessage(message) }  \u00a0\u00a0\u00a0\u00a0}  }  ```<\/code><\/pre>\n<p>\u041e\u0431\u0449\u0438\u0439 \u043a\u043e\u0434 \u043c\u043e\u0434\u0443\u043b\u044f \u0444\u0438\u0447\u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0433\u043e\u0442\u043e\u0432, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u0430 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e grpc-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043d\u0430\u0448\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b.<\/p>\n<p><a class=\"anchor\" name=\"%D1%88%D0%B0%D0%B35\" id=\"\u0448\u0430\u04335\">5&#8243;><\/a><\/p>\n<h3>\u0428\u0430\u0433\u00a05. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u00a0proto-\u0444\u0430\u0439\u043b\u0430\u043c<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0435\u0440\u0435\u043c \u0444\u0430\u0439\u043b \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 <a href=\"https:\/\/github.com\/grpc\/grpc-go\/blob\/master\/examples\/helloworld\/helloworld\/helloworld.proto\" rel=\"noopener noreferrer nofollow\"><u>helloworld.proto<\/u><\/a> \u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 <code>\/domain\/src\/proto<\/code>:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c wire-\u043f\u043b\u0430\u0433\u0438\u043d \u043a \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u043c\u0443 \u043c\u043e\u0434\u0443\u043b\u044e. \u0412\u0441\u0435 \u0448\u0430\u0433\u0438 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e <a href=\"https:\/\/github.com\/DevTchernov\/grpc-sample\/commit\/253f609834e75e7dc1da21f15e12f9124f0297dd\" rel=\"noopener noreferrer nofollow\"><u>\u0441\u043e\u0431\u0440\u0430\u043d\u044b \u0432 \u043e\u0434\u0438\u043d \u043a\u043e\u043c\u043c\u0438\u0442<\/u><\/a>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>libs.versions.toml<\/code> \u0434\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u0421 \u043d\u0435\u0433\u043e \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c:<\/p>\n<ol>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e <code>wire<\/code> \u0432 \u0441\u0435\u043a\u0446\u0438\u044e [versions]:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` # wire wireVersion = \"4.0.0-alpha.15\" ```<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043f\u043b\u0430\u0433\u0438\u043d \u0432 \u0441\u0435\u043a\u0446\u0438\u044e [libraries]:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` # wire wireGradle = { module = \"com.squareup.wire:wire-gradle-plugin\", version.ref = \"wireVersion\"} wireRuntime = { module = \"com.squareup.wire:wire-runtime\", version.ref = \"wireVersion\"} wireGrpcClient = { module = \"com.squareup.wire:wire-grpc-client\", version.ref = \"wireVersion\"} ``` <\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0446\u0435\u043f\u043b\u044f\u0435\u043c \u0441\u0430\u043c \u043f\u043b\u0430\u0433\u0438\u043d \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0432 <code>\/mpp-library\/domain\/build.gradle.kts<\/code>:<\/p>\n<ol start=\"3\">\n<li>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>Wire<\/code> \u0445\u043e\u0441\u0442\u0438\u0442\u0441\u044f \u043d\u0430 <code>jitpack.io<\/code>, \u0443\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043e\u0442\u0442\u0443\u0434\u0430 \u0432 <code>\/build-logic\/build.gradle.kts<\/code>:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` repositories {     mavenCentral()     google()      gradlePluginPortal()     maven(\"https:\/\/jitpack.io\") } ```<\/code><\/pre>\n<ol start=\"4\">\n<li>\n<p>\u0418 \u0437\u0434\u0435\u0441\u044c \u0436\u0435 \u0441\u0430\u043c \u043f\u043b\u0430\u0433\u0438\u043d \u0432 <code>dependencies<\/code>:<\/p>\n<\/li>\n<\/ol>\n<pre><code>``` dependencies {   ...   api(\"com.squareup.wire:wire-gradle-plugin:4.0.0-alpha.15\") } ```<\/code><\/pre>\n<ol start=\"5\">\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-334716","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334716","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=334716"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334716\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=334716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=334716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=334716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}