Xcode与Swift开发小记
Xcode下使用Swift的笔记实录
文章目录
引子
鉴于React Native目前版本在iOS上开发遇到诸多问题,本以为搞RN只需理会Javascript开发,没想到冒出CocoaPod的一堆编译问题。所以横下一条心,决定直接进攻iOS本身。不管你是用React Native,还是用Flutter,iOS下的直接编程Swift或OC都是绕不过去的坎。
Xcode比Android Studio要香,模拟器运行快,当然配置更复杂。
十年前的2014年,苹果发布了Swift , 五年后的2019年,又发布SwiftUI。从此iOS开发的面貌焕然一新。
Swift 的最新版本是Swift 5.5,该版本于2021 年9 月发布。
SwiftUI 是Apple 开发的一种UI 框架,它首次在iOS 13 中引入,支持iOS、iPadOS、macOS、watchOS 和tvOS 等Apple 平台。 当前最新版本的SwiftUI 是在Xcode 13 中引入的SwiftUI 3.0。
Xcode工程结构核心概念
每一门编程语言都会有namespace, module, package这些基本概念,但定义上都存在一些差异。这些差异会影响到加载和相互调用关系。所以,学习一门编程语言,首要是弄清楚这些基本概念是如何定义的。
Xcode里有两个概念和其它开发工具不同,一个叫Schema,一个叫Target。Schema可以理解为解决方案,一个Schema可以对应不同的Target,生成物也不同。
- Project和Workspace
- Package:包是Swift Package Manager的概念,不是Swift语言的概念,包的根目录下需要存在一个Package.swift描述文件
- Target: 通常也被称为build target,也就是构建的目标
- 在创建项目的时候默认就会创建一个target,有时被称为主target
- 一个工程里可以创建多个target,每个target都对应相应的模板
- 一个包里可以有一个或多个target,也就是一个target列表。
- 一个target是一个app bundle 或 framework。每个target构建后对应一个库或一个可执行文件作为product。
- target之间存在依赖关系,可以在Xcode里定义某个target依赖哪些其它target
- Module:很多编程语言里一个文件对应一个module,但Swift不是。
- 模块是代码的集合,对应一个或多个文件,里面定义Swift的 类、函数等
- 一个模块对应一个发布单元
- 一个module就可以看成是一个project中的一个target,这个target的默认模块名称就是这个项目的名称(可以在target的Build Settings—Product Module Name配置)
- 在同一个模块中所有的Swift类处于同一个命名空间,它们之间不需要导入就可以相互访问
- namespace: 一个class或一个struct就定义一个namespace,或者说一个{}就对应一个namespace
- Swift有命名空间,而Objective-C没有。
- Swift并没有namespace这个关键字
- Bundle:Xcode 工程项目本身就是在一个 Bundle 之下,开发者可以使用 Bundle.main 来获取其中的资源
- Library 和 Framework:
Modules: Swift organizes code into modules. Each module specifies a namespace and enforces access controls on which parts of that code can be used outside of the module.
A program may have all of its code in a single module, or it may import other modules as dependencies. Aside from the handful of system-provided modules, such as Darwin on macOS or Glibc on Linux, most dependencies require code to be downloaded and built in order to be used.
When you use a separate module for code that solves a particular problem, that code can be reused in other situations. For example, a module that provides functionality for making network requests can be shared between a photo sharing app and a weather app. Using modules lets you build on top of other developers’ code rather than reimplementing the same functionality yourself.
Packages: A package consists of Swift source files and a manifest file. The manifest file, called Package.swift, defines the package’s name and its contents using the PackageDescription module.
A package has one or more targets. Each target specifies a product and may declare one or more dependencies.
namespace与文件名和路径无关,只与模块名有关。这一点不同于Java和Python。在Xcode中,创建group和folder是有区别的,group参与编译,创建group可以选择不创建folder,folder下文件不参与编译。folder是蓝色的,它是以文件夹的形式存在;group是黄色的,它是以分组的概念存在。
Swift工程结构示例:
不管你是Run,还是Build,首先要明确你是针对哪个Schema。如下,你要选择对应的Schema才行。
创建了两个Target,其中一个是Unit Test,依赖主target。
Swift语法速记(TODO)
每一门编程语言都喜欢用不同的方式做和别人相同的事情。不知道这是故意标新立异,还是真的有某种道理,难道设计者不知道Java和C的语言风格已经成了大众的习惯吗?对于程序员来说只能选择接受。例如定义函数的关键字就有def, func, function等,Swift也不例外,也搞了一套自己的语法糖。
- 常量用let,变量用var
- 函数参数有标签,有名称,返回类型用箭头,传参需带参数名,要吐:-)
- 字符串可以用单引号或双引号,多行字符串用三个单引号或三个双引号
- 数组、Set、字典都是用中括号定义,都可以用for-in遍历
var shoppingList: [String] = ["Eggs", "Milk"] //数组
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"] // 集合
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"] // 字典
- as, as?, as!的区别:as向上转,as!向下转。不确定向下转型可以成功时,用类型转换的条件形式(as?),只有你可以确定向下转型一定会成功时,才使用强制形式(as!)
- ??左边为nil的时候,取右边
- 扩展: 扩展可以给一个现有的类,结构体,枚举,还有协议添加新的功能。类似与Javascript的原型机制
- 协议:类似于Java的接口
- subscript:用来索引对象。下标可以定义在类、结构体和枚举中,是访问集合、列表或序列中元素的快捷方式。
- guard, if…else, if let用法的区别
- ForEach需要item符合 Identifiable协议,如 ForEach(items, id: .pageId){}
- mutating关键字
- any和some:any 吾不知其为何物也,some 吾知其为何物,但不知道其具体实例
- 闭包。闭包作为参数在Swift中被普遍应用。尤其是尾随闭包,要习惯它的写法。
小技巧
单元测试中使用await
func testImageFetching() async throws {
let (data, _) = try await URLSession.shared.data(from: url)
}
SwiftUI中使用List
List {
ForEach(items, id: \.id) { item in
Text(item.name)
}
}
View中取数据
.task is iOS 15+, so could go back to .onAppear if you need iOS 13+.
页面跳转
最常见的是采用NavigationLink:
NavigationLink(
destination: DetailView(landmark: landmark)
.environmentObject(self.userData)
) {
RowView(landmark: landmark)
}
在Swift界面项目中使用Apple的SF Symbols图标
可以使用SFsymbols客户端来查看所有支持的图标,systemName就是图标的名称:
常见问题
Xcode添加package时连接github超时
由于Xcode不能直接设置代理,所以稳妥方式是手工下载github代码,再添加时选Local:
刷新几把Xcode,有时需要关闭项目或关闭Xcode再重启,然后给target添加上对这些包的依赖即可:
官方给的解决方案是:
On the terminal xcodebuild -scmProvider system -resolvePackageDependencies -disablePackageRepositoryCache -workspace MyProject.xcworkspace -scheme MyScheme
On XCode after the xcodebuild finishes XCode - File - Packages - Resolve Package Versions.
Xcode无法修改快捷键,一闪而过
输入法改成自带的英文,不要用搜狗
参考链接
更多推荐
所有评论(0)