技术标签: 2024年程序员学习 ios cocoa macos
创建好KMM项目后我们需要添加Compose跨平台的相关配置。
首先在settings.gradle文件中声明compose插件,代码如下所示:
pluginManagement {
repositories {
google()
gradlePluginPortal()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
plugins {
val composeVersion = extra["compose.version"] as String
id("org.jetbrains.compose").version(composeVersion)
}
}
这里compose.version的版本号是声明在gradle.properties中的,代码如下所示:
compose.version=1.3.0
然后我们在shared模块中的build文件中引用插件
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
id("com.android.library")
id("org.jetbrains.compose")
}
并为commonMain添加compose依赖,代码如下所示:
val commonMain by getting {
dependencies {
implementation(compose.ui)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.runtime)
}
}
sync之后,你会发现一个错误警告:uikit还处于试验阶段并且有许多bug…
uikit就是compose-jb暴露的UIKit对象。为了能够使用,我们需要在gradle.properties文件中添加如下配置:
org.jetbrains.compose.experimental.uikit.enabled=true
添加好配置之后,我们先来运行下iOS项目,确保添加的配置是无误的。
果然,不运行不知道,一运行吓一跳
这个问题困扰了我两三天,实在是无从下手,毕竟现在相关的资料很少,经过N次的搜索,最终解决的方案很简单:Kotlin版本升级至1.8.0就可以了。
kotlin("android").version("1.8.0").apply(false)
再次运行项目,结果如下图所示。
不过这是KMM的iOS项目,接下来我们看如何使用Compose编写iOS页面。
我们替换掉iOSApp.swift中的原有代码,替换后的代码如下所示:
import UIKit
import shared
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let mainViewController = Main_iosKt.MainViewController()
window?.rootViewController = mainViewController
window?.makeKeyAndVisible()
return true
}
}
上面的代码看不懂没关系,我们只来看获取mainViewController的这一行
let mainViewController = Main_iosKt.MainViewController()
Main_iosKt.MainViewController是通过新建在shared模块iOSMain目录下的main.ios.kt文件获取的,代码如下所示:
fun MainViewController(): UIViewController =
Application("Login") {
//调用一个Compose方法
}
接下来所有的事情就都可以交给Compose了。
因为页面这部分是公用的,所以我们在shared模块下的commonMain文件夹下新建Login.kt文件,编写一个简单的登录页面,代码如下所示:
@Composable
internal fun login() {
var userName by remember {
mutableStateOf("")
}
var password by remember {
mutableStateOf("")
}
Surface(modifier = Modifier.padding(30.dp)) {
Column {
TextField(userName, onValueChange = {
userName = it
}, placeholder = { Text("请输入用户名") })
TextField(password, onValueChange = {
password = it
}, placeholder = { Text("请输入密码") })
Button(onClick = {
//登录
}) {
Text("登录")
}
}
}
}
上述代码声明了一个用户名输入框、密码输入框和一个登录按钮,就是简单的Compose代码。
然后需要在main.ios.kt中调用这个login方法:
fun MainViewController(): UIViewController =
Application("Login") {
login()
}
运行iOS程序,效果如下图所示:
嗯~,Compose 在iOS上UI几乎可以做到100%复用,还有不学习Compose的理由吗?
在之前的第1弹和第2弹中,我们分别实现了在Desktop、和Web端的网络请求功能,现在我们对之前的功能在iOS上再次实现。
首先在shared模块下的build文件中添加网络请求相关的配置,这里网络请求我们使用Ktor,具体的可参照之前的文章:KMM的初次尝试~
配置代码如下所示:
val commonMain by getting {
dependencies {
...
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
}
}
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-darwin:$ktorVersion")
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-android:$ktorVersion")
}
}
这里我们仍然使用「wandroid」中的每日一问接口 :wanandroid.com/wenda/list/…
DemoReqData与之前系列的实体类是一样的,这里就不重复展示了。
创建接口地址类,代码如下所示。
object Api {
val dataApi = "https://wanandroid.com/wenda/list/1/json"
}
创建HttpUtil类,用于创建HttpClient对象和获取数据的方法,代码如下所示。
class HttpUtil {
private val httpClient = HttpClient {
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
}
}
/**
* 获取数据
*/
suspend fun getData(): DemoReqData {
val rockets: DemoReqData =
httpClient.get(Api.dataApi).body()
return rockets
}
}
这里的代码我们应该都是比较熟悉的,仅仅是换了一个网络请求框架而已。现在公共的业务逻辑已经处理好了,只需要页面端调用方法然后解析数据并展示即可。
由于Android、iOS、Desktop三端的UI都是完全复用的,所以我们将之前实现的UI搬过来即可。代码如下所示:
Column() {
val scope = rememberCoroutineScope()
var demoReqData by remember { mutableStateOf(DemoReqData()) }
Button(onClick = {
scope.launch {
try {
demoReqData = HttpUtil().getData()
} catch (e: Exception) {
}
}
}) {
Text(text = "请求数据")
}
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数HarmonyOS鸿蒙开发工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年HarmonyOS鸿蒙开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/22a0eaf1a058e35576dff2510f3b69ae.png)
![img](https://img-blog.csdnimg.cn/img_convert/8586e3cde39e49d323cb1f5cdb56fb08.png)
![img](https://img-blog.csdnimg.cn/img_convert/48132677115d039c03276e0667ac88b4.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新**
**如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)**
![img](https://img-blog.csdnimg.cn/img_convert/0a1cac567b193e773473b2165e1a0887.png)
**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上HarmonyOS鸿蒙开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新**
**如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注鸿蒙获取)**
[外链图片转存中...(img-d6L9gRS7-1712828388209)]
**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
文章浏览阅读243次。Day2-打印打印打印!我终于更新了!(哭腔)一、 最简单的打印最最简单的打印语句: print(“打印内容”)注意:python是全英的,符号记得是半角下面是我写的例子:然后进入power shell ,注意:你需要使用cd来进入你保存的例子的文件夹,保存时名字应该取为xxx.py我终于知道为什么文件夹取名都建议取英文了,因为进入的时候是真的很麻烦!如果你没有进入正确的文件夹..._puthon打印任务收获
文章浏览阅读1k次。centos8问题参考CentOS 8 EOL如何切换源? - 云服务器 ECS - 阿里云_"cenerrors during download metadata for repository \"appstream"
文章浏览阅读2.7k次,点赞3次,收藏11次。SpringBoot+Maven+MabatisPlusmaven在新建springboot项目引入RELEASE版本出错maven在新建springboot项目引入RELEASE版本出错maven详解maven就是通过pom.xml中的配置,就能够从仓库获取到想要的jar包。仓库分为:本地仓库、第三方仓库(私服)、中央仓库springframework.boot:spring-boot-starter-parent:2.2.1.RELEASE’ not found若出现jar包下载不了只有两_基于微服务的在线教育平台尚硅谷
文章浏览阅读1k次。数据库备份的方法第一种:使用mysqldump结合exec函数进行数据库备份操作。第二种:使用php+mysql+header函数进行数据库备份和下载操作。下面 java 实现数据库备份的方法就是第一种首先我们得知道一些mysqldump的数据库备份语句备份一个数据库格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 --database 数据库名 ..._java数据备份
文章浏览阅读3.4k次,点赞2次,收藏14次。window10_ffmpeg调试环境搭建_win10如何使用mingw64编译ffmpeg
文章浏览阅读6.3k次,点赞9次,收藏14次。给大家推荐《考试脑科学》这本书。作者介绍:池谷裕二,日本东京大学药学系研究科教授,脑科学研究者。1970年生于日本静冈县,1998年取得日本东京大学药学博士学位,2002年起担任美国哥伦比亚大学客座研究员。专业为神经科学与药理学,研究领域为人脑海马体与大脑皮质层的可塑性。现为东京大学药学研究所教授,同时担任日本脑信息通信融合研究中心研究主任,日本药理学会学术评议员、ERATO人脑与AI融合项目负责人。2008年获得日本文部大臣表彰青年科学家奖,2013年获得日本学士院学术奖励奖。这本书作者用非常通俗易懂_考试脑科学pdf百度网盘下载
文章浏览阅读4.8k次,点赞17次,收藏51次。Linux的命令有几百个,对程序员来说,常用的并不多,考虑各位是初学者,先学习本章节前15个命令就可以了,其它的命令以后用到的时候再学习。1、开机 物理机服务器,按下电源开关,就像windows开机一样。 在VMware中点击“开启此虚拟机”。2、登录 启动完成后,输入用户名和密码,一般情况下,不要用root用户..._ls-lmore
文章浏览阅读4.1k次。1.登录MYSQL系统命令打开DOS命令框shengfen,以管理员的身份运行命令1:mysql -u usernae -p password命令2:mysql -u username -p password -h 需要连接的mysql主机名(localhost本地主机名)或是mysql的ip地址(默认为:127.0.0.1)-P 端口号(默认:3306端口)使用其中任意一个就OK,输入命令后DOS命令框得到mysql>就说明已经进入了mysql系统2. 查看mysql当中的._mysql -u user
文章浏览阅读484次。一、lvs简介和推荐阅读的资料二、lvs和keepalived的安装三、LVS VS/DR模式搭建四、LVS VS/TUN模式搭建五、LVS VS/NAT模式搭建六、keepalived多种real server健康检测实例七、lvs持久性工作原理和配置八、lvs数据监控九、lvs+keepalived故障排除一、LVS简介和推荐阅读的资料 学习LVS+Keepalived必须阅读的三个文档。1、 《Keepalived权威指南》下载见http://..._this is the redundant configuration for lvs + keepalived server itself
文章浏览阅读795次,点赞20次,收藏15次。AIDL是使用bind机制来工作。java原生参数Stringparcelablelist & map 元素 需要支持AIDL其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。下图是我进阶学习所积累的历年腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
文章浏览阅读248次。承接:数据基础02
文章浏览阅读2.8w次,点赞14次,收藏88次。文章目录1. 概念:Narrow Width Effect: 窄宽度效应Short Channel effects:短沟道效应阈值电压 (Threshold voltage)2. 阈值电压与沟道长和沟道宽的关系:Narrow channel 窄沟的分析Short channel 短沟的分析1. 概念:Narrow Width Effect: 窄宽度效应在CMOS器件工艺中,器件的阈值电压Vth 随着沟道宽度的变窄而增大,即窄宽度效应;目前,由于浅沟道隔离工艺的应用,器件的阈值电压 Vth 随着沟道宽度_短沟道效应