在 MAS 软件内调用 Apple Script

 • 

最近写了一个小软件 WebDrop ,尝试了下上架,关于如何在沙盒内调用 Apple Script 写一点相关的内容。
先看一个 Code Snippet

NSAppleScript *script= [[NSAppleScript alloc] initWithSource:@"tell application \"Safari\" to return URL of front document as string"];
    NSDictionary *scriptError = nil;
    NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&scriptError];
    if(scriptError)
    {
        NSLog(@"Error: %@",scriptError);
    } else
    {
        NSAppleEventDescriptor *unicode = [descriptor coerceToDescriptorType:typeUnicodeText];
        NSData *data = [unicode data];
        NSString *result = [[NSString alloc] initWithCharacters:(unichar*)[data bytes] length:[data length] / sizeof(unichar)];
    }

这段代码会返回当前 Safari 最前 Tab 的网页地址,但是只限于没有开启 App Sandbox 的情况 —— 如果开启了 Sandbox,就会出现以下错误:

2016-06-24 10:41:10.022 WebDrop[81536:1628248] Error: {
    NSAppleScriptErrorAppName = Safari;
    NSAppleScriptErrorBriefMessage = "\U5e94\U7528\U7a0b\U5e8f\U6ca1\U6709\U8fd0\U884c\U3002";
    NSAppleScriptErrorMessage = "\U201cSafari\U201d\U9047\U5230\U4e00\U4e2a\U9519\U8bef\Uff1a\U5e94\U7528\U7a0b\U5e8f\U6ca1\U6709\U8fd0\U884c\U3002";
    NSAppleScriptErrorNumber = "-600";
    NSAppleScriptErrorRange = "NSRange: {61, 6}";
}

其中的 Unicode 为:“应用程序没有运行。”,这是因为沙盒阻止 Apple Script 访问 Safari 了,这个时候有两个解决办法。

第一个见 http://objccn.io/issue-14-2/,首先这个方法好像是不能上 MAS 的,因为其中采用的方法是安装 .scpt 到用户文件夹下,我用这个方法上架时审核人员给出以下的理由:

Performance - 2.4.5  
Your app installs an AppleScript in shared locations.  
Specifically the app installs an AppleScript into the Application Scripts folder.

我也不知道为什么审核人员不给用这种方法,而必须要求 Apple Script 储存在 Container 内 (参见 stackoverflow),不过既然如此,就只能用另一个方法了...

第二个就是加 Entitlement key,有两个 key 可以添加,一个是 com.apple.security.scripting-targets (Reference),一个是 com.apple.security.temporary-exception.apple-events (Reference),其中前者更推荐,使用起来是这样的:

<key>com.apple.security.scripting-targets</key>
    <dict>
        <key>com.apple.mail</key>
        <array>
            <string>com.apple.mail.compose</string>
        </array>
    </dict>

后者的话简单一些,不用配置特定的动作,只要写 bundle id 就可以(注意要全小写)

<key>com.apple.security.temporary-exception.apple-events</key>
	<array>
		<string>com.google.chrome.canary</string>
		<string>com.google.chrome</string>
		<string>com.apple.safari</string>
		<string>com.vivaldi.vivaldi</string>
		<string>org.webkit.nightly.webKit</string>
	</array>

2016.6.20

 • 

最近没有怎么写日记,主要是考试周了,然后没有产出什么东西(虽然 Youtube 倒是看了不少)。
WWDC 看了三个 Session,分别是 222,604 和 609。其中 604 是关于 SceneKit 的。一星期前我还在 V2EX 上说 SceneKit 并不适合用来学习做三维游戏,原因还是那么几个,其中包括 SceneKit 不支持 PBR 这个事情。不过今年的 WWDC 上 SceneKit 开始支持 PBR,也支持一些基本的相机效果(Motion Blur, Bloom, Color Grading)了。
至于使用起来的效果,Session 里演示是非常好的,不过我自己用起来还是有些问题,包括 Xcode-beta 在编辑 .scn 时崩溃,导入 .exr 文件必须是 6-sided 不能是 panorama 不然也崩溃(估计是长宽比的问题),以及之前都没有的导入 .dae 层级混乱的问题。等到考试后再细细研究,反正 Hyperions 是需要用到这些新特性的。
升级了 iOS 10,iPad 上的 Swift Playground 挺震撼,因为可以 import Foundation,UIKit,甚至 SceneKit,也就意味着可以做很多事情,虽然还是受限于 Playground,不过有这个开头,以后出现 Xcode for iOS 也不是什么令人惊讶的事情吧。目前我能看到最接近这个目标的是 Dringend,一个在 iOS 上的本地的 Objective-C/Swift 编辑器,可以远程连接 Mac 编译 in-house ipa 到 Dropbox 然后安装。
Swift Playground 和 Working Copy 可以配合使用,Working Copy 是一个 iOS 上的 git 客户端,支持 push 操作,并且可以作为 Document Provider,即 Swift Playground 里对文件所有的修改都是直接在 Working Copy 的目录里实现的。
顺带一说,明年一定要申请 WWDC 奖学金...今年五月份在公司干活耽误申请了,等到明年估计也攒的有些钱了,应付机票什么的都没太大问题了吧。
最近还在用 Gyroscope,一个个人量化的工具,主要是颜值高(逃,其实这类工具本身就是要做的颜值高才有人用,因为用户消费的就是这个高科技的感觉,如果没有一套 FUI,基本上就和这种感觉无缘了。

2016.6.10

 • 
  • New Project : Hyperions

    简而言之,是一个三维版本的 BuildBox,运行在 iPad 和 iPhone 上。
    基于 SceneKit,布局仿照我日常使用 Unity 的布局:左边 Scene 和 Player,右边 Hierarchy 和 Inspector,顶部放置运行/暂停键。当然在竖排的 Size Class (iPhone 和 iPad Slide View)中布局还是改为了上下分栏。
    计划中要写的功能有:支持从 Dropbox 导入贴图和模型,然后提供一个软件内的材质编辑器(虽然 SceneKit 的自带材质还没支持 PBR),提供简单的挂载 Component 功能(这部分我记得 GameplayKit 自带),提供一个和 Keynote 一样的 Remote 功能,让 iPad 里的场景可以实时在 iPhone 里面预览(玩)。

  • Updated Website : FinGameWorks
    网址:http://fingameworks.github.io/ ,拿到工资后续费了 Apple Developer,软件重新上架,就把之前做的几个东西的链接放在了上面。

  • House of the Dying Sun 上架 Steam 了,虽然我没买,不过还是有些感想的。本身我也就是喜欢太空题材的人,做 Epoch 之前就发现了很多开发中的类似主题(太空,战斗,飞行,etc)的游戏,House of the Dying Sun 算是其中一个。这个游戏的开发者在他的 Dev Blog 里面写了快两三年,现在终于上架了。

2016.6.6

 • 
  • 看完了 TRON Uprising,19集的动画剧,遗憾的是没有续集。
  • 去深圳面基,见到了 Yuno 和袁晨皓,一起参加 hackathon,不过因为参加 hackathon 的原因光顾着写代码了,没有怎么聊天,等下次吧
  • Segment Fault 和 Angel Hack 举办的深圳 Hackathon,一等奖。要不是没有牌子的话陈叔又可以贴一张了。
  • Uber Guide 很神奇地被 Uber 的工程师注意到了,希望后面能接触下。
  • 最近听了很多关于 iPad 用作生产力工具的播客,入手 Coda for iOS 后发现用虚拟键盘的话任何 iOS 设备都不是一个好的生产力设备。
  • 最近还用了 Quadro,Actions 的继任者。但是给我的印象并不好,主要是因为 Quadro 采取了订阅付费方式,当然是有一个买断制的价格,但是那个价格已经超过一个正常工具软件应有的价值,并且新的工具在网络连接稳定性上根本不能和 Actions 相比较,不知道是不是因为 Quadro 是用外包团队做的(无意冒犯外包,但作为一个需要长久更新和支持,特别还是订阅制的工具类软件,如果仍然把技术外包,我觉得有些不太专业)。

About A Crappy Website

 • 

Project Crap 其实第一开始并不叫这个名字,原本这个基于 three.js 的页面是一个更正经的项目的实验品,我打算用 three.js 写一个 WebGL 版的简历来着 —— 至于为什么是简历,没有什么特殊原因,主要是因为能用三维渲染作为载体的文字内容实在是太少了,没人会用这套技术做什么博客的,当然我见过一个做过程生成的图形学菊苣这么干过,但我并不觉得刚入门网页开发(宽泛的,前后端兼有的)的我能这么干。我个人感觉这套技术比较适合做 PPT 或者个人项目展示这类逻辑简单,需要即时加载,可以在手机端运行的交互内容,相比而言,Unity WebGL 更适合做严肃意义上的网页三维游戏,即使什么都不写打包也要几兆,又太过重了。
写偏题了,为什么半路上放弃写成简历,因为写着写着到周一早上了,想起来还有课,然后缓过神来再看自己在写的东西,突然觉得: WTF am I writing !?
总是会有这种半夜充满激情要做一个东西,白天再看就觉得没有意义的状态。于是就草草了事,把原本的 Audio Loader 也注释掉,后面介绍的内容也删了,加一个装作 Chrome 崩溃的图片吧!于是就有了一个代码一团糟的半成品:http://crap.justzht.com/
顺带简单谈下 three.js 的使用体验:

  • 和大多数即时渲染的东西使用起来差不多,相机,光,几何体,全屏后期处理,等等。
  • threejs 仓库自带了很多全屏相机效果,使用时和 unity 把后期效果的 compoment 挂到相机差不多,就是建一个 composer,然后按顺序一个个把 shaderPass 放进去,每一帧调用下 render 方法就行
  • 正确的写法应该是和 Unity 一样,subclass Object3D 或者 Mesh,然后在这个 class 里面写一个 function 调用 requestAnimationFrame(); 作为每帧调用的方法,后面就和 Unity 在 FixedUpdate 或者 Update 写法差不多了,我把所有的玩意都写到了一个 <script></script> 里面实在是作死。
  • unity 的 DOTween 实在是好用,然后我发现 js 里面竟然也有类似的东西:tweenjs,语法类似,写起位移动画不用操心。
  • 建立一个 LoadingManager 放在最前面,然后每个图片,贴图,音频或模型的 Loader 就可以在建立的时候传参 LoadingManager 进去,这样可以通过 Manager 知道所有素材的加载情况,等待加载完成后再进入主界面。
  • threejs 优点在于运行在浏览器上,任何设备都可以运行,可以读取设备陀螺仪,可以在网页上模拟 VR 的镜头畸变,至于性能就不要过于纠结了,虽然我没有详细去研究优化就这么说有些不负责任,但是我觉得与其在网页应用上纠结帧速,不如好好研究下怎么在 Unity 原生应用里面降低 drawcall ,成效更快。

2016.5.27

 • 

最近两周:

  • 第一周 写公司 Unity 工程
  • 第二周 写公司 iOS 工程
  • 学了基础的 Rails
  • 写了 Project SodaProject Fragment
  • 给 Project Soda 加了 SSL 证书
  • 基本没去上课
  • 看了很多 Youtube 搞笑视频
  • 吃了很多垃圾食品

觉得最近代码写太多了 不是个好事情。倒不是说写代码久坐对健康不好,健康这种事我一般也不操心,而是说感觉好久没有做其他方向的事情了,比如做做设计,做做建模,什么的。
说到建模,OTOY 的人终于回复我了,说就算我们给你学生证书你也只能用老版本的 Octane Render,我们在搞一个新的订阅方式,你要愿意来参与试用的话就回复邮件。于是我就回信说好好好好我愿意,结果对方又放我鸽子,到现在也没有什么动静,我觉得他们的工单系统几乎是废的。
然后我最近又在捣鼓 World Machine,拖拖节点生成贴图,放 C4D 渲染一下。一个直观的感觉是如果只导出 Height Map 和 Color Map 的话,至少需要 8K 分辨率才能达到比较好的效果 —— 然而如果要导出 16K 的话内存就不够了。有可能靠高度图 和 Deformer 不是生成地形最好的方式,回头再研究下,运气好的话可以做出来一些抽象的东西 —— 就是 Behance 上经常能看到的那种。

Mountain View

 • 

Quick Demo.

Texture : World Machine, 8K Resolution
Model : C4D Dispatcher Deformer with height map
Render : C4D Default

再谈坚果手机

 • 

博客里写过两次我买的坚果手机 不过这款手机一直没有真正地用过 —— 当时只是想作为 iPhone 的备用机,不过因为软硬件都不稳定的问题就闲置在那里。然后我换了新 iPhone,备用机就变成了老 iPhone,而坚果手机现在则成了只能进 Fastboot 的砖头,我也懒得去返厂了。
理论上如果还能进 Fastboot 就没什么大问题,毕竟有 flash recovery 这个命令嘛,我之前也在博客里面写过一次。但是坚果手机的 ROM 自从升级到 2.5.3 版本后连这个命令都不响应了,我是不太清楚出了什么问题,据说是官方给封了这条路,当然也只是据说,不过从官方一贯的选择(不给 root)来看,似乎也合情合理。
现在看来坚果手机官方设想的设计的哲学应该是这样的:

  • 易用的界面(启动器,图标,各种交互优化)
  • 强硬的手段(不允许第三方 Recovery,不允许 Root)

看上去很像 iPhone 的风格,毕竟 iPhone 也是一贯对于 hacker 不友好的设备,大家也都习惯了,以至于如果你在 Youtube 上看到类似于 "iPhone Life Hacks" 的视频,大都是些无伤大雅的系统自带功能而已,被一群无聊的人说来说去,营造出一种“我是 PowerUser 我最屌”的虚荣感。至于越狱,在国内也已经被 Adhoc 分发的各种第三方 App Store 打败了,毕竟大部分人越狱都只是想下付费软件而已,如果不用越狱就可以下载付费游戏,还有多少人关心越狱。至于在 iPhone 上跑 OpenSSL,Who cares?
扯远了,回到这两条设计哲学上来。我的坚果从拿到手就一直不稳定(参见之前拿到手第一天就黑屏)。如果我的 iPhone 出现了这种情况,那么想必我会毫不犹豫地送修或是换机,而不是尝试进各种刷机界面,因为我知道,这台手机基本没救了,因为以 iPhone 的软件质量来看这肯定是硬件问题,而且我就算想救,iPhone 上也没有 fastboot,也没有 recovery 可以进,它就是一台要么工作正常,要么损坏彻底的手机,没有任何给用户手动维修的希望。我觉得这个才是这两条设计哲学贯彻正确的结果。
**如果你想要用户不去 root ,为什么还要提供进入刷机界面的可能性呢。**这是我当时在浏览完坚果官方论坛的感想,然后也不知是该高兴还是悲伤,坚果果然在更新新版本后连安卓手机基本的长按按键进 Recovery 的功能都没有了,高兴的是卧槽坚果还真这么干了,悲伤的是这是我见过的估计是最激进的安卓手机厂商,恢复和刷第三方是有区别的,iPhone 不能刷第三方但有恢复模式,但是对于安卓手机来说,Recovery 承担着恢复和刷第三方两个功能,一旦不能进入 Recovery,意味着恢复也无可能。
然而反讽的是,锤子是靠 ROM 起家的,当年给 HTC One X 出的 Alpha 版本 ROM 我还在 XDA 论坛里面羞耻地宣传过。这么一家靠 ROM 成名并且目前还在给众多其他品牌机型适配自己 ROM 的公司,反倒不让自己的手机有任何刷机的可能性,可以说是在贯彻以 iPhone 为代表的设计哲学,但这么自相矛盾,包括甚至还在做外发应用,把启动器都做成了其他手机可以运行的版本,也是interesting。

2016.5.15

 • 

Lackarindie apps 推荐里面看到了一个蛮有趣的小游戏叫做 30SecondLife 遂下载下来玩了一会。风格让我想到了以前在彭博周刊和 Quartz 网站上玩过的那种炒股小游戏:从1959到2010随机选一段时间压缩到一分钟,给你本金,整个过程只能有一次买入和卖出,你能跑赢大市么?
两个游戏都是把十几年压缩成十几秒 没时间思考 而炒股小游戏相对于 30SecondLife 更甚的地方在于整个游戏只有两次操作机会 —— 时间压缩让你能够更快地预览到选择的结果,也能让你更无法确定什么时候下注。
30SecondLife 这种点击类游戏最近还玩了一个 就是马老师安利的 Bitcoin Billionaire 戳戳戳 挖比特币 也是消磨时间的小游戏 不过很容易上瘾....
说到游戏,EPOCH 终于在最新的 Unity 5.3.4p5 上复活了,虽然仍然有些问题,不过总算没有在 Editor 内崩溃。好像做太空游戏就是一个劫难,其他使用游戏引擎的项目,比如之前做的 AR 软件,或是现在在公司做的 Gear VR 内软件都没有什么太大的引擎上的问题,最多需要些时间找解决方法,然而一旦开始做太空游戏 不论是 Unreal 还是 Unity 都会出现严重的问题 导致整个项目不能进行下去 等到什么时候更新了引擎 突然又奇迹般的复活了。
不过以现在的眼光看,五个月前写的 EPOCH 结构实在是太乱了,而且过程生成的 Noise Map 这个功能并没有写进去,这块反而是后来 SceneKit 实验性写的 EPOCH Remastered Version 包含了使用 NoiseLib 生成噪声图的功能,所以不如直接新开一个工程重写算了。
感觉整个 16 年就没有什么实质性的进展,开源的 iOS 控件没继续写,Dribbble 也没更新,EPOCH 这个游戏又因为各种事情进度一直在拖,Hackathon 上一次参加还是一月份的了,自己又因为未来的规划问题和父母一直争论,反反复复耗尽精力。希望下半年能更有成果些吧。