前语

本期是 Swift 编辑组自主收拾周报的第二十二期,每个模块已开始成型。各位读者假如有好的提议,欢迎在文末留言。

欢迎投稿或引荐内容。现在计划每两周周一发布,欢迎情投意合的朋友一同加入周报收拾。

若方针远大,就要有大动作。若寻求杰出,便须有大改变。Swift社区已整装待发,你要不要一同呢?

周报精选

新闻和社区:Apple Vision Pro 和 visionOS 撼世上台

提案:移除由特点包装器引起的 Actor 阻隔揣度

Swift 论坛:为什么只能将结构附加到数组一次

引荐博文:Swift OpenAPI Generator 的介绍

话题评论:

你以为企业实施薪资保密有哪些利弊

新闻和社区

注册 WWDC23 实验室和活动

Swift 周报 第三十一期

经过在线实验室和活动这种绝佳办法,你能够在一整周内与 Apple 工程师、规划师和专家进行交流交流。

一对一实验室 从开发的根底知识到杂乱概念,你都能够在这里取得个性化辅导。了解怎么运用全新 Apple 技能、探究 UI 规划原则、优化产品在 App Store 上的形象,以及更多主题。

活动 每日都有许多精彩的活动在 Slack 中打开。

在 Q&A 中就工程和规划主题发问。 在大家一同观看讲座视频期间加入或重视实时对话,并与演讲者进行 Q&A。 在社区暖场活动中了解其他开发者和 Apple 团队。 体会最新的框架,尝试各种规划理念,并在学习区同享你的创造。 在 6 月 6 日,与业内的佼佼者比试一下专业知识问答。 实验室和活动对 Apple Developer Program 和 Apple Developer Enterprise Program 的一切成员,以及 2023 Swift Student Challenge 参赛者敞开。

Apple Vision Pro 和 visionOS 撼世上台

Swift 周报 第三十一期

Apple Vision Pro 是一款革命性的空间计算设备,可完成数字化内容与实在国际的无缝融合,让用户在沉溺于当下的一同还能与别人交流交流。在 Apple Vision Pro 中,各种 App 将突破传统显示器的束缚限制,具有一幅无边的画布。此外,Apple Vision Pro 还推出了一个全三维用户界面,而操控这个界面,仅需求用户的眼睛、双手和语音 — 最自然、最直观的输入东西。Apple Vision Pro 搭载了全球首个空间操作系统 visionOS,让用户能够以一种绝妙的办法与数字化内容互动,好像它们真的存在于实际国际之中。Apple Vision Pro 选用了突破性规划:在显示方面,选用超高分辨率显示屏系统,两块显示屏的总像素为 2,300 万;在功用方面,选用一起的双芯片规划并搭载定制的 Apple 芯片,保证每一刻的体会都实在无比,让人沉溺当下。

探究丰富实用的资源,助你经过一种全新而又了解的办法将空间计算方面的构思变为实际,打造出能够重新界说交流、效率和文娱的 App。

App Store 中新增的隐私功用

在 Apple,咱们将隐私视作每个人的基本权利。因而,咱们构建了许多功用来协助用户了解开发者在隐私以及数据搜集和同享方面的做法,让用户能够自主掌控他们的数据。经过 App 盯梢透明度 (ATT),用户能够挑选 App 是否有权盯梢用户在其他公司的 App 和网站内的活动,以便投进广告或者与数据代理商同享。借助隐私标签和 App 隐私陈述,用户能够检查 App 搜集哪些数据以及怎么运用这些数据。

许多 App 会利用第三方软件开发东西包 (SDK),这些东西包能够供给超卓的功用,但或许会对 App 处理用户数据的办法发生影响。为了让开发者能够更轻松地打造超卓的 App,一同告知用户数据运用状况并尊重他们在这方面做出的挑选,咱们推出了两项新功用。

首先,为了协助开发者了解第三方 SDK 怎么运用数据,咱们推出了新的隐私清单。隐私清单是一份文件,会以单一标准格局概述 App 中第三方代码的隐私做法。当开发者预备分发他们的 App 时,Xcode 会将开发者运用的一切第三方 SDK 中的隐私清单合并为一个简单易用的陈述。这个陈述内容全面,总结了 App 中的一切第三方 SDK,使开发者能够更轻松地创立更精确的隐私标签。

此外,为了向用户供给额定的隐私保护,假如 App 引证的 API 或许会被用于指纹识别(在 App Store 中被禁止的一种做法),现在需求挑选合理的原因来解说为什么运用此 API 并在隐私清单中声明已运用此 App。在这个过程中,App 有必要精确描绘其对于这些 API 的运用状况,而且只能出于隐私清单中所述的原因而运用这些 API。

第二,咱们期望协助开发者改善软件供应链的完整性。运用第三方 SDK 时,开发者或许很难知道他们下载的代码是不是由期望的开发者编写的。为了处理这个问题,咱们推出了适用于 SDK 的签名功用,这样一来,当开发者在 App 中选用新版本的第三方 SDK 时,Xcode 将验证它是否由同一开发者签名。这个功用将对开发者和用户都非常有协助。

咱们将在今年晚些时分发布更多信息,包含:

影响隐私的 SDK 列表 (对用户隐私发生严重影响的第三方 SDK) “需求指明原因”的 API 列表,运用它们时有必要给出合理的原因 开发者反馈表,用于就调用触及的 API 提出新的原因 其他文档,具体介绍签名和隐私清单、他们的优势以及何时需求运用它们

提案

正在检查的提案

SE-0400 Init 拜访器 提案正在检查。

该提案的意图是,Init 拜访器将特点包装器的离线初始化特性泛化,使得类型中的任何计算特点都能够挑选参与确定性初始化分析,而且能够替代运用自界说初始化代码对一组存储特点进行初始化。

SE-0401 移除由特点包装器引起的 Actor 阻隔揣度 提案正在检查。

SE-0316:大局 Actors 引入了像 @MainActor 这样的注释,将类型、函数或特点阻隔到特定的大局 Actor。还引入了各种规矩,用于揣度大局 Actor 阻隔。如下:

@propertyWrapper
struct UIUpdating<Wrapped> {
  @MainActor var wrappedValue: Wrapped
}
struct CounterView { // infers @MainActor from use of @UIUpdating
  @UIUpdating var intValue: Int = 0
}

该提案主张在运用 Swift 6 语言模式编译时移除此揣度规矩。根据上面的示例,CounterView 在 Swift 6 中将不再揣度 @MainActor 阻隔。

Swift论坛

  1. 提议SE-0400: Init Accessors

SE-0400:Init Accessors 314 的检查从现在开始,一直继续到 2023 年 6 月 26 日。

  1. 提议改善提案模板以取得更好的功用实践

介绍

强制性东西链和示例项目以及 Experiment It 部分将答应开发人员在提案检查期间更轻松地进行实验并参与评论。

动机

实验正在检查的功用这是评估提案的重要办法,即使是写得很好和具体的提案也能够从让开发人员实验它中受益。 提案模板能够改善,使任何人在检查期间更简单试用提议的功用。

建议的处理方案

将以下标题字段增加到提案模板:东西链和示例项目以及新的 Experiment It 部分。

东西链

该字段应指向一个链接,从中能够下载一个 swift 东西链,其间该功用是在实验性标志下完成的。

现在大多数提案只说到主分支中有一个功用可用,尽管大多数时分该功用都在 Swift.org 上可用的开发快照中 – 下载 Swift 对于新手来说了解这一点并不是那么微不足道,有时还有一个提案检查期 甚至在没有作业快照的状况下发动。

该链接应该从第一天起就可用,并在审核期间尽或许更新。

一种或许性是在网站下载页面上增加一个额定的部分,其间包含专用于正在检查的提案的东西链,这能够答应东西链可用,即使由于某种原因它不能出现在主快照中也是如此。

  1. 发问为什么只能将结构附加到数组一次?

我的使用程序的方针是提醒用户与他们接近的人互动。 因而,我的使用程序首要运用两个结构体,称为 Relation(代表一个人)和 Interaction(代表与人的一次交互)。

我构建了一个名为 “NewInteractionSheet” 的作业表,其方针是向关系的交互数组之一增加一个新的交互。

在增加交互时,此作业表非常有用。 可是,由于某种原因,它只能作业一次。 为什么要这样做? 这便是我想要弄清楚的。

这是 “NewInteractionSheet.swift” 代码的一部分:

import PhotosUI
import CoreLocation
import MapKit
struct NewInteractionSheet: View {
    @Binding var isPresentingNewInteractionView: Bool
    @Binding var relations: [Relation]
    @State private var newInteraction = Interaction.emptyInteraction
    @State private var relation: Relation = Relation.emptyRelation
    @State private var isPresentingLocationPicker: Bool = false
    var body: some View {
        NavigationView {
            Form {
                Section("You interacted with...") {
                    RelationPicker(relations: $relations, relation: $relation)
                }
                Section("Interaction details") {
                    InteractionDatePicker(dateToSet: $newInteraction.date)
                    TypePicker(typeToSet: $newInteraction.type)
                    DurationPicker(shouldShow: newInteraction.type.hasDuration,
                                   hoursToSet: $newInteraction.durationHours,
                                   minutesToSet: $newInteraction.durationMinutes)
                    SummaryTextField(summaryToSet: $newInteraction.summary)
                    LocationPicker(shouldShow: newInteraction.type.hasLocation,
                                   coordinatesToSet: $newInteraction.location.coordinates,
                                   locationNameToSet: $newInteraction.location.name,
                                   isPresentingLocationPicker: $isPresentingLocationPicker)
                    InteractionPhotosPicker(images: $newInteraction.pictures)
                }
            }
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Dismiss") {
                        isPresentingNewInteractionView = false
                    }
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button("Add") {
                        if let index = relations.firstIndex(where: { $0.id == relation.id }) {
                            print("\nBefore appending to relations")
                            print(relations[index])
                            print(newInteraction)
                            relations[index].interactions.append(newInteraction)
                            print("\nAfter having appended to relations")
                            print(relations[index])
                            print(newInteraction)
                        }
                        isPresentingNewInteractionView = false
                        //AJOUTER LA PLANIFICATION D'UNE NOTIFICATION
                    }
                }
            }
            .navigationTitle("New interaction")
        }
    }
}

正如在代码中看到的,我包含了三个“打印”指令来协助我调试它。 当我尝试增加两个交互时,以下是操控台中打印的内容:

Before appending to relations
Relation(id: EA18AAD4-E576-49A9-90BF-CC58C5000ECE, firstName: "Johanna", lastName: "Duby", photo: nil, interactions: [], contactFrequency: 1814400.0, birthday: Optional(2023-06-15 14:34:40 +0000), notes: "", theme: Relations.Theme.blue, reminders: nil)
Interaction(id: 106CD832-1949-4800-AC75-E21B8890E580, date: 2023-06-15 14:34:43 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])
After having appended to relations
Relation(id: EA18AAD4-E576-49A9-90BF-CC58C5000ECE, firstName: "Johanna", lastName: "Duby", photo: nil, interactions: [Relations.Interaction(id: 106CD832-1949-4800-AC75-E21B8890E580, date: 2023-06-15 14:34:43 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])], contactFrequency: 1814400.0, birthday: Optional(2023-06-15 14:34:40 +0000), notes: "", theme: Relations.Theme.blue, reminders: nil)
Interaction(id: 106CD832-1949-4800-AC75-E21B8890E580, date: 2023-06-15 14:34:43 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])
Before appending to relations
Relation(id: 8D3D2012-D8A2-4092-B1A9-D476F7E05B9A, firstName: "Nastassja", lastName: "Ferrari", photo: nil, interactions: [], contactFrequency: 1209600.0, birthday: nil, notes: "", theme: Relations.Theme.green, reminders: nil)
Interaction(id: 5C4EE2E1-7D2D-4E32-BC00-FCA781EC8C20, date: 2023-06-15 14:34:49 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])
After having appended to relations
Relation(id: 8D3D2012-D8A2-4092-B1A9-D476F7E05B9A, firstName: "Nastassja", lastName: "Ferrari", photo: nil, interactions: [], contactFrequency: 1209600.0, birthday: nil, notes: "", theme: Relations.Theme.green, reminders: nil)
Interaction(id: 5C4EE2E1-7D2D-4E32-BC00-FCA781EC8C20, date: 2023-06-15 14:34:49 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])
  1. 发问Swift 5.9 是否支撑嵌套/递归宏?

  2. 发问怎么引证不同模块中的文章?

检查 DocC 代码链接的语法,好像咱们有办法引证同一模块中的文章:

doc:GettingStarted

可是咱们不能运用前导斜杠语法来指定模块相对路径,因为它现已被 tutorials 命名空间占用:

doc:/tutorials/SlothCreator

怎么引证来自不同模块的文章?

答复:

库存 DocC 尚不支撑外部 – 或者更具体地说,没有供给公共处理方案。 早期的 DocC 代码中有一些关于答应某些过程的外部引证解析器的位,@ronnqvist 一直在研讨更新的处理方案(“分层解析器”)——但我只重视了一些 PR(最近的一个 提取了很多旧代码:经过 d-ronnqvist 增加成功解析的外部引证到参阅索引, Pull Request #582)

  1. 发问Macros包会嵌入到App中吗?

例如,当我运用 #stringify Swift 宏在我的使用程序中生成代码时,它会在编译期间用新代码替换我的一些源代码。 那么这个宏包会随我的使用程序一同供给吗? 或者它只是在编译期间发生

答复:替换发生在编译时。 宏方针不应链接到使用该方针中包含的宏的代码。

  1. 发问哪个 Apple Networking Api 用于 UDP 多播和单播?

一般来说,iOS 开发和网络的新手。 开发一个游戏节目类型的使用程序,其间“主机”设备需求多播到“参赛者”设备。 参赛者设备也需求能够呼应。 实际上传递的信息很少,但速度很重要,因而运用 UDP。

我一直在研讨苹果设备的一些常用网络 api:network.framework、CocoaAsyncSocket、Multipeer-Connectivity、BSD 套接字等。总的来说,我倾向于只运用高级 network.framework 但缺少 示例和资源使决议计划变得困难。 任何定见,将不胜感激。

答复:TN3151: Choosing the right networking API

引荐博文

Swift OpenAPI Generator 的介绍

摘要: Swift OpenAPI Generator是一个 SwiftPM 插件,它能够生成客户端代码或服务器端代码,以便处理 HTTP 调用。 OpenAPI 是一种用于记载HTTP服务的标准,能够运用YAML或JSON编写,并可被东西读取,以协助自动化作业流程,例如生成必要的代码以发送和接纳HTTP恳求。Swift OpenAPI Generator 能够协助咱们经过 OpenAPI 文档描绘HTTP恳求和呼应的结构,包含 HTTP 办法、 URL 路径和查询参数、HTTP状态码和内容类型,运用 JSON Schema 描绘呼应体的结构,使得咱们能够在开发使用程序时生成网络代码,而不需求手动编写和保护网络代码,专注于核心事务逻辑。要运用 Swift OpenAPI Generator 插件,需求增加 SwiftPM 依靠项以及运行时库和传输完成,然后运用生成的API客户端或服务器端存根。 Swift OpenAPI Generator 支撑大多数常用特性,但仍有一些特性需求完成,项目盯梢开展状况能够运用 GitHub issues

Swift 宏:运用新的表达办法扩展 Swift

摘要: Swift 宏是在 Swift 5.9发布的一项新功用,它答应你经过自界说编译时检查和生成新的代码,在编译时将它们写入到你的文件中,然后消除冗余的样板代码。本文讲解了宏的作业原理、怎么编写自界说宏以及怎么进行测验,以验证一个答应在编译时验证 URL 并在 URL 有用时返回解包值的宏的比如。本文还评论了宏的不同角色,包含独立和附加宏,并解说了为什么你或许考虑在代码中运用宏。

在 Swift 服务器端 Vapor 和客户端使用之间同享 Swift 代码

摘要: 这篇博客评论了在客户端使用和后端服务器之间同享 Swift 代码的优点以及怎么经过 Swift 包和 Vapor 完成这一方针。经过同享模型和端点界说,您能够保证两个侧面都运用相同的层,防止出现意料之外的恳求失败。博客供给了界说软件包结构、露出模型、同享端点界说和在后端软件包中配置端点的代码示例。此外,它供给了一个通用办法,用于恳求端点并在客户端使用中运用它们。作者还说到了优化适用于一切支撑的 HTTP 办法的代码的重要性。

话题评论

薪酬保密作为人力资源管理中一项颇具争议的行动,近年来学界对其研讨越来越多。有人提出,实施薪酬保密,能让企业根据职工绩效的高低供给差异较大的薪酬,提升薪酬激励作用,一同也能防止因为收入距离发生内部冲突。也有人提出公开的薪酬准则能使内部交流更为有用,削减误传,增强信任感,作为一种准则,薪酬的等级体系、岗位距离以及操作程序还应以公开为准则。你以为企业实施薪资保密有哪些利弊?

1.保护职工个人隐私。

2.防止职工之间的比较和妒忌心思,削减内部矛盾。

3.难以检查薪资公正性,更少的保密性意味着更多的相等。

4.易发生职工对公司不信任,让职工发生长期处于被剥削的感觉。

关于咱们

Swift社区是由 Swift 爱好者一起保护的公益安排,咱们在国内以微信大众号的运营为主,咱们会同享以 Swift实战SwiftUlSwift根底为核心的技能内容,也收拾搜集优秀的学习资料。

特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 供给优质内容,为 Swift 语言的开展奉献自己的力气。