Arc 浏览器使用体验

过去一周时间,尝试了 Arc 浏览器。体验可以说是非常的好,甚至将其设置成了默认浏览器。同时也将 iOS 上的默认浏览器也切换成了 Arc。可惜没有 iPad 版,iPad 上的版本是 iOS 的兼容版。

喜欢的点

  • 淡化 URL

Arc 访问 Web,更像是访问本地应用,如果网络足够快,Web 应用体验很好,使用过程中要比现有的浏览器有更好的沉浸感。甚至在使用的某一个瞬间几乎忘记是在使用Web 应用。

  • 多 Space

所谓的 Space,就是使用场景。使用场景之间的切换真是方便太多了,只需要手指左右滑动,即可完成场景的切换。工作和个人的 Space 切换,让不同内容互不干扰。

  • 将默认搜索引擎从 Google 切换成了 Perplexity

目前还不敢确认能否最终替换 Google。因为经过过去一周的使用,除了每天在第一次使用的时候会触发 Cloudflare 的安全检测以外,又发现一个新的问题,就是对给出的结果还是不太多元化。

怎么说呢?在大多数时候,Perplexity 给出的前六个搜索结果都还行。但如果想探求更多的不同信息,想要进一步交叉验证,就变得有些困难。不过,对于大多数使用场景,其实体验已经很好了,这一点还是有一说一。

  • 方便的 Split 双开

Arc 可以很方便的左右双开,加上自带的笔记功能,可以左边打开在线资料,右边打开笔记,一边看资料,一边做笔记,非常的方便和自然。

体验了一次左边开YouTube 视频讲解,右边做笔记,非常丝滑。

  • iOS 版本不是 macOS 版本的延续

iOS 版本跟 macOS 版本没有什么太大的关联,基本上交互是自成体系。iOS 版本的使用体验目前也还挺好的,自有其特色。关键还是脑袋里不要总是想着 macOS 版本与 iOS 版本有什么关联就还好。

  • 实用的小工具

macOS 版本有很多很实用的小工具。比如快速的截屏工具,可以自定义网页的 Boost 工具,以及提供可以在线分享文档,也就是上边提到的笔记可以通过在线链接的方式分享给第三方。

  • AI 加持

现在 AI 已经深入到各个产品,Arc 也不例外,提供了很多 AI 加持的工具,比如 iOS 版本对网页的归纳总结功能。macOS 版本通过 ChatGPT 直接回答问题等。

不完美的点

  • 没办法将 macOS 版本的密码同步到 iOS 版

目前来看,这个功能还在探索中,想必还没有考虑清楚。原因么,大概也是因为 iOS 版本的交互跟 macOS 版本差异太大,统一的技术方案还在探索中吧。另外,Windows 版本还在研发阶段,开发资源或许比较紧张吧。

  • 基于 Chromium 的 macOS 版本还不够完美

目前 macOS 版本一旦涉及到 Chromium 的个别设定,还是会有一些瑕疵或者说小 bug,但是不至于影响使用。只不过让强迫症会有些难受。

  • macOS 版本的密码没办法导出

macOS 的密码除了不能与 iOS 版本同步以外,还不能独立导出。如果将 Safari 或者 Chrome 的密码导入,那么此时就无法将密码导出。所以这也是目前让我将密码导入变的很犹豫的点。

总结

Arc 是真的好用,完全打破了之前使用浏览器的使用体验。如果 Arc 能够流行起来,我大概率会从开发 App 产品重新优先考虑 Web 产品,原因就是因为在 Arc 上使用 Web 产品真的很像使用 App。

SwiftUI 中的 @State 与 @Binding 和 @ObservableObject 与 @ObservedObject 以及全局 @EnvironmentObject 的极简示例

SwiftUI 提供了一套强大的属性包装器,帮助管理状态和数据流。以下是这几种属性包装器的定义和用法。

  1. @State 和 @Binding:

• @State

@State 是一个属性包装器,用于在 SwiftUI 视图中声明本地状态。当 @State 变量的值改变时,它将使视图失效,并促使视图重新渲染。它通常用于简单的本地组件状态,这些状态不需要共享给其他视图。

例如:

import SwiftUI

struct Content: View {
    @State private var isToggled = false

    var body: some View {
        Toggle("Switch", isOn: $isToggled)
    }
}

• @Binding

@Binding 是一个属性包装器,它提供了对一个 @State 属性的引用,或者其它 @Binding 属性的双向绑定。它允许不同的视图共享对同一状态的访问,并能相互更新状态。

例如,使用 @Binding 将状态传递到子视图:

import SwiftUI

struct Content: View {
    @State private var isToggled = false

    var body: some View {
        ChildView(isToggled: $isToggled)
    }
}

struct ChildView: View {
    @Binding var isToggled: Bool

    var body: some View {
        Toggle("Switch", isOn: $isToggled)
    }
}
  1. @ObservableObject 和 @ObservedObject:

• @ObservableObject

这是一个协议,当遵从该协议的类的某些属性被标记为 @Published 时,这些属性在发生变化会通知其订阅者。通常用于定义外部的数据模型或状态,这些模型或状态将被多个视图访问和修改。

import Combine
import SwiftUI

class MyModel: ObservableObject {
    @Published var isToggled = false
}

struct Content: View {
    @ObservedObject var model = MyModel()

    var body: some View {
        Toggle("Switch", isOn: $model.isToggled)
    }
}

• @ObservedObject

这个属性包装器用于声明一个视图要观察的 ObservableObject 实例。当这个实例的 @Published 属性发生变化时,它会重新渲染视图。

  1. @EnvironmentObject:

@EnvironmentObject 是一个属性包装器,用于从环境中获取一个由某个父视图提供的 ObservableObject 实例。这对于跨多个视图共享数据模型非常有用,不必显式地将模型一层一层传递下去。

例如,在根视图中提供环境对象,并在子视图中访问它:

import Combine
import SwiftUI

class SharedModel: ObservableObject {
    @Published var isToggled = false
}

struct Content: View {
    @StateObject var model = SharedModel()

    var body: some View {
        ChildView()
            .environmentObject(model)
    }
}

struct ChildView: View {
    @EnvironmentObject var model: SharedModel

    var body: some View {
        Toggle("Switch", isOn: $model.isToggled)
    }
}

使用 @EnvironmentObject 之前,需要确保在视图层级中的某个点已经往环境中注入了对象,通常是在视图树的顶层进行。如果在环境中找不到相应的对象,那么试图访问 @EnvironmentObject 会导致运行时错误。

如何将 Xcode 中 Vim 模式下的 JK 按键映射到 ESC 按键

自从 Xcode 推出 Vim 模式,我就研究了一下如何在 Xcode 中开启。

有趣的是我在日常使用中并不会将 Xcode 作为常用编辑器。甚至可以更绝对一些,日常工作学习中几乎就不会使用 Xcode。一来是因为 Xcode 太「重」,启动很慢。二来也不开发 iOS App。开启 Vim 模式的原因仅仅是因为好奇,加上日常自己写代码使用 Vim 较多,所以就想感受一下在 Xcode 中使用 Vim 是怎样一种体验。

对于 Vim 的使用,虽然会有很多快捷键,但使用最频繁的就是 ESC 按键。我在自己的 Vim 设置中,就是将 ESC 按键映射到了 JK 两个按键,也就是连续快速点击「J」和「K」就会触发 ESC 按键。

但 Xcode 并没有提供 Vim 模式下的自定义按键的映射功能。最近重新学习 iOS 开发,对于 ESC 按键的映射实在忍无可忍。终于让我找到了一种「曲线救国」的方案。

实现这个功能的是一款 macOS 系统下的开源键盘映射软件,名字叫「Karabiner-Elements」。

首先,直接到官网下载最新的版本。

接着,按照官方文档的截图示意进行授权安装。安装过程包括开启对应的系统权限,相应的根据提示开启即可。官方文档的步骤很详细,还配了截图,步骤不算多,很快就能设置完。

安装完成之后,本地启动「Karabiner-Elements」App,点击窗口左侧的「Complex Modifications」,如下图所示:

点击右侧设置界面顶部的「Add your own rule」按钮,将弹窗里的默认配置删除。打开 Gist 页面,复制里边的 json 配置信息,将其原封不动的粘贴到弹窗里,点击弹窗右上方的「Save」按钮,保存配置。完成之后即可看到一条名为「jk to escape for xcode」的配置。

此时,在Xcode 中开启 Vim 模式(如果已经是开启状态,可以直接体验),即可享有 「J」「K」 按键映射到 ESC 按键的丝滑体验。

Gist 中的配置是我根据网上找到的一份配置稍微进行了的修改,如果想自行修改配置,可参考官方配置手册

如何在 Xcode 点击 command+S 保存时,自动对 Swift 代码进行格式化

开始学习 SwiftUI,发现 Xcode 貌似没有自动格式化的功能。网上找了一些资料,有些教程里的截图已经过时了,简单摸索后,重新总结了一下。

完成此功能,一共需要三步:

  1. 安装 SwiftFormat-for-xcode 插件
brew install --cask swiftformat-for-xcode
  1. 系统设置

插件安装完成后,需要先进行系统设置,路径如下:

系统设置 -> 隐私与安全性 -> 扩展 ->Xcode Source Editor

点击 Xcode Source Editor,出现一个弹窗,将 SwiftFormat勾选上。

此时,重启 Xcode,完成后会在 Xcode 的 Editor 选项下方出现 SwiftFormat 选项,说明 SwiftFormat 已经安装完成。

但如果想在 Xcode 点击 command + s 保存的时候执行格式化,还需要最后一步设置。

  1. keyboard 快捷键设置

按照如下路径,从系统设置进入:路径如下:

系统设置 -> 键盘 -> 键盘快捷键(键盘导航下方) -> App 快捷键

点击窗口右侧的 + 按钮,如下图所示添加快捷键:

其中 「Format File」可以根据你喜好编辑为「Format Selection」或「Lint File」,点击「完成」即全部设置完毕。

此时,在 Xcode 中编辑代码后,点击 command + S 保存时,会自动执行 Xcode 中 SwiftFormat 功能。

在学习Swift

这段时间一直在学习 Swift 这门语言,平时闲暇时间都用来学习或思考人生了,所以这些天没怎么写东西。

经过这几天学习,发现 Swift 这门语言挺好的,你别说还挺喜欢。如果专注 Apple 生态开发,Swift 是绕不过去的「砍」。

如果这么说,让人感觉 Swift 是一道坎。这门语言学起来概念确实有点儿多,而且关键字也多,但是一旦掌握,代码写起来其实还挺舒服的。很多语法以及关键字的存在,是为了更好的代码阅读体验以及语言的安全性考虑。

关于应用场景,除了开发 Apple 家的 App,还可以做 Server 端的开发。据说去年开始,社区又衍生出了嵌入式的分支。作为独立开发者,对于中小型 Web 项目,Vapor 足够稳定,上手也简单,各种基础设施其实已经挺完善的了。只不过对于企业级的应用,可能相关配套设施还差一些,但这不仅仅是语言本身的问题了。按照现在的发展趋势,假以时日会越来越完善。

Swift 数据类型

Swift 的数据类型很有意思,即便是基本类型其实也是结构体。

值类型 枚举(enum) Optional
值类型 结构体(struct) Bool、Int、Float、Double、character、
String、Array、Dictionary、Set
引用类型(reference type) 类(class)
常见数据类型
  • 整数类型:Int8、Int16、Int32、Int64、UInt8、UInt16、UInt32、UInt64
  • 在32bit平台:Int 等价于 Int32;在 64bit 平台,Int 等价于 Int64
  • 整数的最值:UInt8.max、Int16.min
  • 一般情况下,建议直接使用 Int
  • 浮点类型:Float,32 位,精度只有 6 位;Double,64 位,精度至少 15 位

Swift 语言编译流程

Swift 这门语言编译器的后端是基于 LLVM 的,编译器的前端是 SwiftC,也就是指 Swift 的编译器。

Swift 编译器

Swift 编译器将 Swift 语言编译成 LLVM IR,也就是 LLVM 的中间语言,LLVM
的编译器后端编译成相应的 CPU 可执行文件。

关于 Swift 编译器的相关文档,详情可参考 Swift Compiler 官方文档。

通常,SwiftC 存放在 Xcode 内部:

Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc

一些常见的操作如下:

  • 生成语法树:swiftc -dump-ast main.swift
  • 生成最简洁的 SIL 代码:swiftc -emit-sil main.swift
  • 生成 LLVM IR 代码:swiftc -emit-ir main.swift -o maiin.ll
  • 生成汇编代码:swiftc -emit-assembly main.swift -o main.s

Swift 的编译流程如下所示:

又开始收藏网站书签了

差不多有将近十年时间没有用过类似收藏网站书签的功能了,最多也就是 Safari 或者 Chrome 上点击一下收藏。

近些年,除了工作开发会用到 Chrome 以外,Safari 对于日常使用来说已经足够了。所以过往的十年间,如果说仅仅保存网站链接,或者收藏文章链接,直接就用 Safari 就够了。而且,基于 iCloud 还可以做到三端同步。

这期间也尝试过 Pocket App,但还是没有使用起来,具体的原因嘛,没有功能上特别客观的原因,比如某某功能不支持之类的。但每次使用的时候,总是感觉这个 App 太「笨重」了,很多功能对我来说没有用,每次启动找个链接也不是很方便。所以日常使用过程中,打开的频率就很低,直至最后被系统自动「卸载」。

前些日子,在 Fediverse 上看到有人在用 Raindrop,出于好奇,下载下来试了一下,使用下来,还蛮契合我当前需求的,所以就用了一段时间,功能刚刚好。

这款 App 的核心功能就是书签管理,Apple 生态下可以做到三端同步,还可以备份到 Dropbox 或 Google Drive。对于个人来说,免费功能就够用了。App 启动很快,找链接很方便,不启动的时候也不会乱弹窗。不过呢,弹窗功能日常也是被关掉的,所以日常也不太感受到。

Raindrop 可以跟很多第三方 App 集成,而且还有官方开放的 API,整个生态做的很 open。

这么多年了,书签管理这个需求照理说应该很成熟了,但是到现在还在有人尝试埋坑,🤔

今天开始学习 iOS 开发了。

开始学习的意思是「系统」的重新学习。

虽然十几年前做过两年 iOS 开发,但是如今的 iOS 开发生态已经天差地别。所以对于我来说,就当重新学习了。

为什么要学习 iOS 开发?

因为,想改变世界……嗯,其实是想给自己打工,自由一些。用自己喜欢的技术,做属于自己的产品。

学习的资源是「A Best-in-Class iOS App」,一共五本书。看这系列书籍的分类,还是挺专业的,基本上主要的开发基础都涉及到了。读完这五本书基本上应该就算是入门了,对于 iOS 的开发知识体系应该就会有一个初步的框架,剩下的就可以不断的单点完善这个框架了。