大二一年

 • 

commit history

➕ Acquired :

  • 🐙 GitHub Stars ✖️ 433
    JustinFincher
  • 💩 Weird Projects ✖️ 5
    Project Crap / Project Fragment / Project EPOCH / Project Cetacea / Project Hyperions
  • 👾 Cocoapod Pods ✖️ 2
    JZMultiChoicesCircleButton / JZtvOSParallaxButton
  • 📱 iOS App Store App On Sale ✖️ 2
  • 💻 Mac App Store App On Sale ✖️ 1
    WebDrop
  • 🏁 Hackathon Prizes ✖️ 4
    hACKbUSTER
    SF Beijing No.1 / UBER Beijing No.3 / CAA Hangzhou No.1 / SF Shenzhen No.1
  • 🏀 Dribbble Player ✖️ 1
    JustZht
  • 🏀 Dribbble Shots ✖️ 13
  • 🐸 New Skills ✖️ 4
    Rails / CSS / MODO / Subtance Painter

🖥 Devices

+ iPad mini 2
+ Dell P2214H
+ GTX 960
+ iPhone 6s
- iPhone 5s
+ Pencil by 53
+ Ten One Design Mountie

👜 Jobs

+ RavenTech : Unity & iOS Intern
+ Fin GameWorks : Indie Game Developer

🙃 Life

+ 18000+ Songs / Music
Xiami / Soundcloud / Spotify
+ 67 Games, 344.2h Playing Time, 66% Games Not Played
Steam

🤖 Next

  • Finish Project EPOCH
  • Finish Project Cetacea & Project Hyperions
  • Learn C4D
  • Make things happen.

在 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。