<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Uiviewcontroller on Chen</title><link>https://hechen.github.io/zh-cn/tags/uiviewcontroller/</link><description>Recent content in Uiviewcontroller on Chen</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 04 Jul 2019 01:19:10 +0800</lastBuildDate><atom:link href="https://hechen.github.io/zh-cn/tags/uiviewcontroller/index.xml" rel="self" type="application/rss+xml"/><item><title>LetsMove 中的几个点</title><link>https://hechen.github.io/zh-cn/post/letsmove/</link><pubDate>Thu, 04 Jul 2019 01:19:10 +0800</pubDate><guid>https://hechen.github.io/zh-cn/post/letsmove/</guid><description>&lt;p&gt;当我们从网络上下载某个 mac app 之后，一般都会默认在 Downloads 目录里，但是某一些 App 是需要放置到 Application 目录才行，最常见的就是自更新功能是受到当前所处目录的限制的，这时候很多下载到本地的 .app 文件打开之后都会弹出提示框，让用户选择是否移动到 Applications 目录，LetsMove 就是大部分 mac app 参考或者集成的开源库，封装了这套逻辑。&lt;/p&gt;
&lt;p&gt;&lt;img alt="LetsMove" loading="lazy" src="https://i.imgur.com/99z1BQf.png"&gt;&lt;/p&gt;
&lt;p&gt;这个库已经好多年了，最近的一次 Commit 是 2017年，其中有几个点可以学习借鉴。&lt;/p&gt;
&lt;h3 id="大致思路"&gt;大致思路&lt;/h3&gt;
&lt;p&gt;虽然叫 Move，实际上是先行 Copy 一份当前的 App Bundle 到 Application 目录，然后杀掉自己并删除源目录的 App 文件。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Move to Applications Folder 确认之后&lt;/li&gt;
&lt;li&gt;复制当前 App 文件到 /Applications 目录中&lt;/li&gt;
&lt;li&gt;删除当前已经打开 App （Mac 上是可行的，不同于 Windows，不存在占用文件句柄的情况）&lt;/li&gt;
&lt;li&gt;执行子进程执行重启过程，具体后文会讲。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="权限获取提权"&gt;权限获取（提权）&lt;/h3&gt;
&lt;p&gt;检查文件路径是否可以写入的方法是 NSFileManager 的 isWritableFileAtPath ，如果返回 false，LetsMove 会主动进行权限获取。&lt;/p&gt;
&lt;p&gt;获取权限所使用的接口是 AuthorizationExecuteWithPrivileges，该接口实际在 OSX 10.7 Lion 之后就已经标记废弃了，但是一直到目前的 macOS 10.14 还一直可以使用。&lt;/p&gt;
&lt;p&gt;而作者为了避免苹果直接移除该代码导致提权接口不可用，使用了动态查找方法的形式，利用 dlsym 查找方法指针来获取，从而避免如果完全移除该方法导致功能不稳定的情况发生。&lt;/p&gt;</description></item><item><title>XPC Services</title><link>https://hechen.github.io/zh-cn/post/xpcservice/</link><pubDate>Thu, 04 Jul 2019 01:01:10 +0800</pubDate><guid>https://hechen.github.io/zh-cn/post/xpcservice/</guid><description>&lt;h2 id="关于-xpc"&gt;关于 XPC&lt;/h2&gt;
&lt;p&gt;因为最近在做的工作涉及到这一块，就大致的记录一下，针对 XPC 技术也做个总结。&lt;/p&gt;
&lt;p&gt;XPC 是 macOS 上一种进程间通信的技术统称，其使得我们可以将 Mac 应用的功能模块拆分成不同的多进程模式，关于进程之间的通信也被系统封装完整了，你只需要按照既定的模式做即可。其带来的最大的好处是&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;提高 App 自身的稳定性&lt;/li&gt;
&lt;li&gt;进行权限隔离&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;拿我目前在做的工作来讲，确实有针对以上这两点的需求。上层业务通过执行脚本命令获取执行结果，执行脚本命令使用的就是 NSTask，大概结构如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt="shared-42f9e747-a47b-46fd-b445-0c7615b41020" loading="lazy" src="https://i.imgur.com/8glAV2u.png"&gt;&lt;/p&gt;
&lt;p&gt;对于执行 NSTask 的这层命令行执行模块来讲，拆分到独立的进程中使得安全性得以提高，即使 XPC 进程挂掉，一般情况下再次向 XPC 通信，系统会自行恢复启用新的 XPC 进程，而主应用无感知。&lt;/p&gt;
&lt;h2 id="xpc-架构"&gt;XPC 架构&lt;/h2&gt;
&lt;p&gt;在 Apple 官方文档中有如下图，很清楚的展示了整个 NSXPC 的架构。&lt;/p&gt;
&lt;p&gt;主应用和 XPC Service 之间是通过 NSXPCConnection 对象保持通信的，其通信接口由 Protocol 定义，然后暴露给外界一个符合了该协议的对象。&lt;/p&gt;
&lt;p&gt;所有的 XPC Service 本身是由系统级别程序 launchd 来管理和维护的。&lt;/p&gt;
&lt;p&gt;&lt;img alt="NSXPC_intro_2x-337fb6a3-4df5-47b3-a322-e52c48905753" loading="lazy" src="https://i.imgur.com/OdvfZk4.png"&gt;&lt;/p&gt;
&lt;h2 id="开发过程"&gt;开发过程&lt;/h2&gt;
&lt;p&gt;整体上主应用和 XPC 通信是标准的 Client-Server 模式。客户端询问 Server 端数据，Server 端应答即可。这之间的数据序列化完全交由系统管理。&lt;/p&gt;
&lt;h3 id="具体步骤"&gt;具体步骤&lt;/h3&gt;
&lt;h4 id="新建-xpc-service-的-target"&gt;新建 XPC Service 的 Target&lt;/h4&gt;
&lt;p&gt;&lt;img alt="Add New XPC Service Target" loading="lazy" src="https://i.imgur.com/BNFRaG7.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Input Target Info" loading="lazy" src="https://i.imgur.com/AyEq9Iv.png"&gt;&lt;/p&gt;</description></item><item><title>Codable &amp;&amp; Tuple</title><link>https://hechen.github.io/zh-cn/post/tuple-codable/</link><pubDate>Mon, 10 Jun 2019 23:50:54 +0800</pubDate><guid>https://hechen.github.io/zh-cn/post/tuple-codable/</guid><description>&lt;p&gt;While learning Swift, I keep finding interesting things. Codable is one of them.&lt;/p&gt;
&lt;p&gt;Today, I defined a model with a tuple type, then Xcode gave me an error. The code might look like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Codable Person" loading="lazy" src="https://i.imgur.com/c67KrA8.png"&gt;&lt;/p&gt;
&lt;p&gt;You may want Xcode to automatically complete all the codable stuff. However, life is hard. Code like this cannot even be compiled. Xcode will tell you that it cannot synthesize Codable for Person because of FullName.&lt;/p&gt;</description></item><item><title>How to generate a NSViewController without a Nib?</title><link>https://hechen.github.io/zh-cn/post/create-nsviewcontroller-without-nib/</link><pubDate>Mon, 03 Jun 2019 20:55:54 +0800</pubDate><guid>https://hechen.github.io/zh-cn/post/create-nsviewcontroller-without-nib/</guid><description>&lt;p&gt;Recently, I created all the ViewControllers through the storyboard or the Nib (for views). Today, when I created a demo project without any Nib file, the ViewController did not show as I expected.&lt;/p&gt;
&lt;p&gt;WTF, Can you believe that? I cannot even create a ViewController now.&lt;/p&gt;
&lt;p&gt;There exist some differences between iOS and macOS.&lt;/p&gt;
&lt;h2 id="ios"&gt;iOS&lt;/h2&gt;
&lt;p&gt;In the previous development on the iOS platform, creating a ViewController — specifically a UIViewController instance — is dead simple, as below.&lt;/p&gt;</description></item></channel></rss>