Gear VRで遊べる面白無料ゲーム6選
先日 Gear VR を購入したDayBySayです。
VRの世界、思ってた以上に楽しいです!楽しすぎて土日が潰れました!辛い。
ということで今回は、Gear VR本体について、あと私が遊んだコンテンツでオススメのものを紹介したいと思います。
※ ゲームパッドがなくても遊べます
Oculus Gear VR
Gear VRは、SamsungとOculusが共同開発しているスマホ装着型のVR用HMDです。
Gear VRの動作環境としては、Samsung製のスマートフォンである Galaxy S6 または S6 edge と、Gear VR の2つのデバイスが必要になります。
没入度が高いHMDの中では、比較的個人で購入しやすい価格レンジになっています( ¥15,000程度
Galaxy S6はだいたい ¥40,000 といったところでしょうか。
元からGalaxyユーザの人手あれば、気軽に環境を作れて良いですね!
詳しくはこちらの公式ページから www.samsung.com
オススメ無料ゲーム6選
前置きが長くなりましたが、オススメのゲームを紹介します!
ちなみに現在リリースされているコンテンツはほとんどが英語になっていますが、英語が読めなくても何となく遊べるのでご安心ください。笑
今回は、遊んでいて気になったプレイ時間と没入感と3D酔いの項目で簡単に評価しています。
Tenple Run VR
↑のモンスターが追いかけてくるので逃げるゲームです。笑
スマホゲーでお馴染みのTempleRunがGear VRでも遊べました。基本的に出来ることはスマホゲーと変わらないですが、振り向くと恐ろしいモンスターがいるので緊張感が半端ないです・・ 何分でも走れるので死ぬほど遊んでしまいました。
個人的には、途中スピードアップしてからはカーブでの3D良いが激しくなりました。3D酔いには個人差があると思いますが、このゲームを遊ぶ前にもう少し優し目のゲームで慣らしたほうが良いかなーと思います。
項目 | 度合い |
---|---|
プレイ時間 | 5分程度 |
没入感 | 中 |
3D酔い | 中 |
Herobound: Gradiators
Herobound Gradiators 敵を倒しながらダンジョンを進んでいくアクションゲームで、最大4人までの協力プレイが可能になっています。私は使いませんでしたが、音声チャットで連絡を取り合いながら遊ぶことも出来るようです。
フィールドを跳ねまわりながら、剣や弓などの武器を持ち替えつつ協力して敵を倒していくのは爽快感があって楽しかったです。弓の攻撃方法に癖があって最初難しかったかな。笑
項目 | 度合い |
---|---|
プレイ時間 | GearVRがヘタるまで |
没入感 | 低 |
3D酔い | 低 |
FindingVR
FindingVRはファンタジックな世界をフックショットとフェアリーを駆使して飛び回るアクションゲームです(こう書くとゼルダっぽい)。ダンジョンの中に潜りながら時には敵を倒し、時には謎解きをしながらおくまで進むゲーム性は少年心をくすぐります。笑
ちょっと3D酔いしましたが、最後のボスも迫力満点で、VRのアクションゲームってこうだよね!というのをいち早く体験したい方にはオススメです。
項目 | 度合い |
---|---|
プレイ時間 | 20分程度 |
没入感 | 中 |
3D酔い | 高 |
Protocol Zero デモ版
Protocol Zeroはモバゲーでお馴染み(?)のDeNAが開発したFPSゲーム。デモ版では敵を倒しながら目的地まで到達するミッションが1つ遊べるようになっています。頭を傾きがゲーム内でも表現されており、壁からちょっとだけ頭を出すみたいなモーションも可能でかなり没入度が高い作品でした。さすがDeNA。
いつか有料版も遊んでみようかなと思わせてくれるデモ版でした。
項目 | 度合い |
---|---|
プレイ時間 | 5分程度 |
没入感 | 高 |
3D酔い | 低 |
InCell
InCellは人の細胞の中を走り回りつつ、ウィルスなどの破壊行為から細胞を護るカーレーシングゲームです。カテゴリとしては教育用のものらしく、楽しみながら人の細胞の仕組みを知ることが出来るゲームのようです。
こちらのゲームは今回体験した中でも一番3D良いが激しかったです。また、ゲーム内の移動がHMDの傾きで起きるのですが、頭を傾けるのと視点移動にギャップを感じて酔うのが辛かったです。ゲームパッドを使えることに気づいてからはだいぶマシでした。
TempleRunを遊んでも余裕だよーという人以外にはオススメできないです。
項目 | 度合い |
---|---|
プレイ時間 | 10分程度 |
没入感 | 中 |
3D酔い | 超高 |
Shironeko VR Project
スマホゲーでお馴染みの白猫プロジェクトのVR版で、今回ご紹介するゲームの中で唯一日本語対応しているゲームです。こちらはソーシャル要素は無いみたいですね。ゲームパッドにも対応しており、操作性もよかったです。ただ視点が360度移動出来る事以外は、スマホゲーとくらべて新しい要素は無いように思いました。とはいえ元々素晴らしいゲームですし、今後の展開次第ではキラーアプリケーションになったりするのでは!?と期待させてくれるゲームなので、一度は遊んでみることをオススメします!
項目 | 度合い |
---|---|
プレイ時間 | 20分程度 |
没入感 | 低 |
3D酔い | 低 |
Gear VR の雑感
VRゲームを長時間プレイしたのは初めてだったので、色々新しい発見がありました。
- 3D酔いヤバイ
- 遊ぶ場所を選ぶ
- ゲームパッドが欲しくなる
3D酔い
ゲームにもよりますが、3D酔いを起こしやすいものと起こしづらい物がありました。
特にレース系のゲームでスピードが早い奴は車酔いに近い状態になった・・ 視点の移動が激しい物は注意です。
遊ぶ場所を選ぶ
自分が向いてる方向がゲーム内の視点に影響するので、よく首を振ることになります。首だけならまだいいですが、体ごと後ろを振り返ろうとして椅子から落ちました。笑
遊ぶときは周りに危ないものがない状態でやるのがベターだと思います。
ゲームパッドが欲しくなる
基本的にはGear VR(とGalaxy)だけで遊べるものが多いですが、ゲームで使う入力のインタフェイスがGear VRの右側についているので、ずっと腕を上げていることになり疲れます。(首も結構疲れます
私は長時間遊びたかったのでゲームパッドを買いました。ゲームパッドを使い始めてからはかなり負担が減ったので、長時間ゲームをする際には必須に近いかなと感じています。
色々試したわけではないですが、私が使っていたゲームパッドは特に不自由もなく良かったのでおすすめです。もちろんGearVRのアプリでなくても利用可能です。
以上!
Unityのコマンドライン引数を使ってパッケージ作成を自動化する
皆さんこんばんは。 思いが強くなりすぎて二郎を食べに新潟まで行ったDayBySayです。
本日はUnity用のプラグインを配布する際に使われるパッケージ(.unitypackage
)作成を自動化する方法について書いていきます。
概要
Unityを用いて開発をされている方はご存知だと思いますが、Unityの世界では便利なライブラリやSDKなどをパッケージとして固めて利用する事がよくあると思います。
作られたパッケージは下記のようにAsset Store経由で配布されたり、GitHub上にホスティングされていたりと、配布方法はいくつか有りますが、形式はほとんどが.unitypackage
形式だと思います。
基本的には、UnityのGUIを用いてパッケージの出力で作成することが可能ですが、これでは人為的ミスが入り込む余地が残ります。
そこで、今回はこの.unitypackage
をの作成を、コマンドライン引数を用いて自動化したいと思います。
docs.unity3d.com
環境
Unity 5.3.2f1
Mac OSX 10.10.5
Projectのディレクトリ構造
$ ls
Assets Library Makefile ProjectSettings README.md
$ tree Assets/ Assets/ ├── Editors │ ├── MyEditor.cs │ └── MyEditor.cs.meta ├── Editors.meta ├── Plugins │ ├── MyPlugin.cs │ └── MyPlugin.cs.meta ├── Plugins.meta ├── Scripts │ ├── MyScript.cs │ └── MyScript.cs.meta └── Scripts.meta
リポジトリ
リポジトリは下記です。 github.com
実装
今回はこんな感じで実装しました。
UNITY_CLI?=/Applications/Unity/Unity.app/Contents/MacOS/Unity LOG_FILE?=unity.log PROJ_PATH?=$(shell pwd) PACKAGE_NAME?=MyPlugin.unitypackage EXPORT_PACKAGES:= Assets/Editors Assets/Plugins Assets/Scripts .PHONY: package all: package: $(UNITY_CLI) \ -exportPackage $(EXPORT_PACKAGES) $(PACKAGE_NAME) \ -projectPath $(PROJ_PATH) \ -batchmode \ -nographics \ -logfile $(LOG_FILE) \ -quit
オプションの説明
-exportPackage と -projectPath
-exportPackage
は名前の通りファイル(ディレクトリ)をパッケージとしてエクスポートするためのオプションで、対象のプロジェクトを-projectPath
で指定する必要があります。
パッケージに含める際に指定するディレクトリは、-projectPath
で指定したプロジェクトから相対パスになります。
今回は-exportPackage Assets/Editors Assets/Plugins Assets/Scripts
となるように指定していますが、今回のディレクトリ構造においては-exportPackage Assets
と等価です。
ちなみに-exportPackage
はディレクトリのみ指定できます(ドキュメントをよく読まずファイルを指定しようとしてハマりました・・哀
-batchmode と -nographics
-batchmode
を設定することで、GUIを使わず実行でき、-nographics
を設定することでグラフィックデバイスの初期化をしないため、GPUを積んでいないマシンでの実行が可能になります。
Unityを介した処理の自動化を行う場合は、基本的にこの2つのオプションを設定することになると思います。
-logfile
-logfile
で実行結果をファイルに書きだしています。
成功しようが失敗しようがここにログが吐かれます。
-quit
バッチ処理終了後に自動でUnityを終了します。
これをしておかないと、処理完了後にUnityのプロセスが残ったままになってしまってうざい感じです。
インポートしてみる
ということで作成したパッケージをインポートしてみました。
指定したディレクトリ以下のファイルがすべてパッケージに含まれているのが確認できました。
まとめ
Unityのコマンドライン引数を使うと自動化が捗る。
あとは世の中のCIサービスがUnity対応してくれれば・・(;_;)
世の中の素敵なslackチームを探すサービスを見つけた
話題のSwift製WebフレームワークKituraをVagrantで手軽に試す
皆さんこんばんは。
腰を気にしていたら背中がやられてきたDayBySayです。
本日は今話題のSwift製WebアプリケーションフレームワークのKitura
の開発環境を作ってみたいと思います。
概要
Kitura
はIBMとAppleのパートナーシップのもと制作されたらしいWebアプリケーションフレームワークです。
さらにIBM BlueMixというPaaSが完全対応しており、クライアントもサーバもSwiftという開発環境を作るにはもってこいであります。
私はまだ使ったこと無いですけど、この記事を読む限り、Push通知用のサーバも簡単に作れるらしい?
料金体系が計算ムズイ系だけれども、どうもPush通知回りは無料枠もあるっぽい。
Parseも死んじゃったし、色々大変だろうけどIBM Bluemixにもちょっとは期待してみよー。
ということで、話を戻すとIBM Blluemix上でも利用できるKitura
を手軽に試す方法について書いていきます。
環境構築
READMEを見るとわかりますが、開発環境としてLinux
、OSX
、Docker
、Vagrant
と、いたれりつくせりで色々用意してくれてます。
個人的な都合により、今回はOSX上でVagrant
を利用する感じで進めたいと思います。
事前準備
VirtualBoxとVagrantを入手します。
開発環境構築
まずは適当な場所にKitura
をクローンします。
$ git clone git@github.com:IBM-Swift/Kitura.git
中身はこんな感じです
$ ls -la total 120 drwxr-xr-x 17 t-sei VOYAGEGROUP\Domain Users 578 3 1 01:57 . drwxr-xr-x 44 t-sei VOYAGEGROUP\Domain Users 1496 3 1 01:57 .. drwxr-xr-x 13 t-sei VOYAGEGROUP\Domain Users 442 3 1 01:57 .git -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 16 3 1 01:57 .gitignore -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 1073 3 1 01:57 .travis.yml -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 649 3 1 01:57 .travis.yml.backup drwxr-xr-x 7 t-sei VOYAGEGROUP\Domain Users 238 3 1 01:57 Documentation -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 10174 3 1 01:57 LICENSE.txt -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 878 3 1 01:57 Makefile -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 1405 3 1 01:57 Package.swift -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 8197 3 1 01:57 README.md drwxr-xr-x 3 t-sei VOYAGEGROUP\Domain Users 102 3 1 01:57 Sources drwxr-xr-x 3 t-sei VOYAGEGROUP\Domain Users 102 3 1 01:57 Tests -rwxr-xr-x 1 t-sei VOYAGEGROUP\Domain Users 1161 3 1 01:57 buildTests.sh -rwxr-xr-x 1 t-sei VOYAGEGROUP\Domain Users 1510 3 1 01:57 build_osx.sh -rwxr-xr-x 1 t-sei VOYAGEGROUP\Domain Users 667 3 1 01:57 runTests.sh -rw-r--r-- 1 t-sei VOYAGEGROUP\Domain Users 3097 3 1 01:57 vagrantfile
次に、Vgarant
の環境を作ります... と言いたいところですが、実は2016/3/1
現在、Kitura
が提供しているVagrant
環境は壊れています。
こちらのPR見るとわかりますが、どうもlibdispatch
回りで不整合が起きてしまっているのが原因のようです。
ということで、今回はこのPRの元になっているブランチを利用してVagrant
の開発環境を作りましょう。
$ git remote add cjwirth git@github.com:cjwirth/Kitura.git $ git fetch cjwirth remote: Counting objects: 43, done. remote: Compressing objects: 100% (43/43), done. remote: Total 43 (delta 25), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (43/43), done. From github.com:cjwirth/Kitura * [new branch] develop -> cjwirth/develop * [new branch] fix-vagrant -> cjwirth/fix-vagrant * [new branch] master -> cjwirth/master * [new branch] travis-ci-tests -> cjwirth/travis-ci-tests $ git co fix-vagrant Branch fix-vagrant set up to track remote branch fix-vagrant from cjwirth. Switched to a new branch 'fix-vagrant' $ vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Fixed port collision for 22 => 2222. Now on port 2200. ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... (中略) ==> default: Compiling Swift Module 'KituraSample' (1 sources) ==> default: Linking Executable: .build/debug/KituraSample ==> default: make[1]: Leaving directory '/home/vagrant/Kitura'
ここまでこれれば準備完了です。
サーバを立てる
まずはVagrant
環境に入ります。
$ vagrant ssh Welcome to Ubuntu 15.10 (GNU/Linux 4.2.0-30-generic x86_64) * Documentation: https://help.ubuntu.com/ Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud
そしておもむろに下記コマンドを叩きます。
$ Kitura/.build/debug/KituraSample INFO: spiListen(_:port:) /home/vagrant/Kitura/Packages/Kitura-net-0.2.0/Sources/KituraNet/HttpServerSpi.swift line 46 - Listening on port 8090
これでVagrant
環境にサーバが立ちました。
初期設定をいじっていなければ、ホストのlocalhost:8090
がゲストの8090
にフォワーディングされる設定になっています。
確認してみましょう。
$ curl localhost:8091 You're running Kitura
成功っぽい! 環境ができたので今日はここまで。
まとめ
Kitura
の提供しているVagrant
の開発環境は現状壊れているので辛い。
Darwin-style フレームワーク内に他ライブラリ・フレームワークへの依存関係を記述する
皆さんこんばんは。
最近腰をやってしまったDayBySayです。
本日はDarwin-styleのフレームワーク内に依存関係を記述する方法についてまとめました。
概要
Mac OSXやiOSで利用されるDarwin-styleのフレームワークですが、サードパーティの誰かがフレームワークを提供する場合に、プラットフォームが提供するライブラリやフレームワークに対して依存関係を持つことが有ります。
例えば、Dropboxが提供しているSDK(フレームワーク)をダウンロードして利用する場合、こちらに書いてあるとおりSecurity.framework
などのフレームワークへのリンクをSDK利用側が明示的に行う必要があり、ちょっとめんどくさいです。
一方で、Googleが提供するAdMobのSDKをダウンロードして利用する場合、フレームワークのリンクを明示的に行う必要はありません。
この違いは、Clang
のLink declaration
を使っているかどうかになります。
Link declaration
先日の記事で書いたClang
のモジュール機能の中に、Link declaration
という依存関係を記述する機能が存在します。
この機能を使うことでフレームワーク側に依存関係を記述し、フレームワーク利用側の負担を減らすことが出来ます。
機能の説明は下記のようにされています。
Link declaration
A link-declaration specifies a library or framework against which a program should be linked if the enclosing module is imported in any translation unit in that program.
説明の通り、モジュールがライブラリ(共有ライブラリを指しています)とフレームワークに対してリンクを行うべきかを定義するものです。
記述方法は下記のような感じです。
link-declaration:
link framework opt string-literal
opt
はframework
記述に対してかかっています。
どういうことかというと、ライブラリ、例えばlibxml2
へのリンクは
link xml2
であり、フレームワーク、例えばAVFoundation.framework
へのリンクは
link framework AVFoundation
となる、ということです。
これらをmodule.modulemap
ファイルに記述することでフレームワーク側で依存関係の記述を吸収することが出来ます。
ちなみに先述のAdMob SDKのmodule.moduemap
はこんな内容になっています。
framework module GoogleMobileAds { umbrella header "GoogleMobileAds.h" export * module * { export * } link framework "AdSupport" link framework "AudioToolbox" link framework "AVFoundation" link framework "CoreGraphics" link framework "CoreMedia" link framework "CoreTelephony" link framework "EventKit" link framework "EventKitUI" link framework "Foundation" link framework "MessageUI" link framework "StoreKit" link framework "SystemConfiguration" link framework "UIKit" // ~~ 略 ~~ }
実際に使ってみる
実際の処理は下記のような感じになっています
#import "HOGEFugaService.h" @import AdSupport; @implementation HOGEFugaService // 中略 + (NSString *)ADID { return [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString; } @end
今回は上記のようにASIdentifierManager
のadvertisingIdentifier
メソッドをフレームワーク内で利用しているため、このプロジェクトで作成されるHOGEFuga.framework
はAdSupport.framework
への依存を持つこととなります。
依存関係を記述するためのmodule.modulemap
は下記のようになっています。
framework module HOGEFuga { umbrella header "HOGEFuga.h" export * module * { export * } link framework "AdSupport" }
link framework "AdSupport"
の記述を追加しました。
動かしてみる
HOGEFuga.framework
を利用する側の実装は下記のようにしています。
import UIKit import HOGEFuga class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. HOGEFugaService.show() NSLog("%@", HOGEFugaService.ADID()) } // 略 }
また、プロジェクトに対してAdSupport.framework
のリンクを明示的に記述していません。
この状態でコンパイルできれば成功です。
Ctrl+R
でシミュレータ実行を行うと・・
コンパイル成功!そしてシミュレータのIDFA
が出力されているので、動作確認も完了です!
まとめ
フレームワークを外部に対して提供する場合は、モジュールとして利用できる形にし、フレームワークへの依存を記述しておくと便利である。
※ CocoaPods
を使う場合リンク機能があるのでモジュールにしなくても済む場合があります
※ Unity
プラグインとしてフレームワークを提供する場合、モジュール化とLink declaration
が有効に働く気がします。
NSUserDefaultsのregisterDefaultsで登録された値を削除する
皆さんこんばんは。 優雅に京都でラーメンを食べているDayBySayです。
今回はタイトルの通りNSUserDefaults
のregisterDefaults
で登録された値を削除することに関しての記事です。
モチベーション
当時開発していたアプリケーションで少々特殊な要件があり、UserAgentを柔軟に変えていくみたいな機能を実装する必要がありました。
iOS9以降でかつWKWebView限定に限定するのであればWKWebView
のcustomUserAgent
を設定するだけで済みますが、その時はiOS8以前もサポートしていたためNSUserDefaults
のregisterDefaults
を使用しており、その場合において1度設定したカスタムなUserAgentからシステムの初期UserAgent状態に戻す方法がわかりませんでした。
ちなみに下記のようにUserDefaults
に設定を行うことでUserAgentのカスタマイズを行っています。
var webview = UIWebView.init() webview.stringByEvaluatingJavaScriptFromString("navigator.userAgent") // ""Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13C75"" NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "CustomUserAgent"]) webview = UIWebView.init() // registerDefaults後に初期化されたものからUAの変更が適用されます webview.stringByEvaluatingJavaScriptFromString("navigator.userAgent") // "CustomUserAgent"
registerDefaults
で登録された値を初期化する
つまり、今回の要件としてはregisterDefaults
に登録された値を初期化すれば良いということになります。
普通に考えれば登録された値を削除するAPIがNSUserDefaults
にありそうな予感がしますが。。
NSUserDefaultsのリファレンスをみてみても、RegistaringDefaultsにはregisterDefaults
のメソッドしか存在しません。
ふむ。。と思いつつも、もう少し探ってみるとregisterDefaults
の説明として下記のような記述がありました。
Discussion
If there is no registration domain, one is created using the specified dictionary, and NSRegistrationDomain is added to the end of the search list.
なるほど。registerDefaults
された値はNSRegistrationDomain
というドメインに保存されるらしいことがわかりました。
つまり、NSRegistrationDomain
の値を書き換える(あるいは削除する)方法がわかれば対応できる可能性が出てきましたね。
NSRegistrationDomain
に登録されている値を削除する
どんなドメインがあるかについてはこちらで多少説明されています。
NSRegistrationDomain
The domain consisting of a set of temporary defaults whose values can be set by the application to ensure that searches will always be successful.
NSRegistrationDomain
は検索を必ず成功させるために設定されるものらしいです。
そういう意味では、値を簡単に削除できないようなインターフェイスになっているのは納得感が有りますね。
ただし今回は削除できないと困るので方法を探して見たところ、- setVolatileDomain:forName:
というドメインの辞書をまるまる上書き出来そうなメソッドを見つけました。
後は、ドメインに登録されている辞書の一覧が取得できればなんとかなりそうですね!と、思いながら探すと- volatileDomainForName:
というなにやら雰囲気のあるメソッドを見つけました。
説明は下記のようになっています。
Returns the dictionary for the specified volatile domain.
Return Value
The dictionary of keys and values belonging to the domain. The keys in the dictionary are names of defaults, and the value corresponding to each key is a property list object (NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary).
ドメインの文字列を受け取って中身の辞書を返す、というように読み取ることが出来ます。
ということで実際に中身を見てみましょう
let registeredDefaults = NSUserDefaults.standardUserDefaults().volatileDomainForName(NSRegistrationDomain) // ["WebKitHiddenPageCSSAnimationSuspensionEnabled": 0, "WebKitMediaControlsScaleWithPageZoom": 0, "WebKitJavaScriptCanAccessClipboard": 0, "WebKitMediaPlaybackAllowsInline": 0, "WebKitLoadSiteIconsKey": 0, "WebKitDisplayImagesKey": 1, "WebKitAVKitEnabled": 1, "WebKitSuppressesIncrementalRendering": 0, "WebKitPictographFont": "AppleColorEmoji", "WebKitFantasyFont": "Papyrus", "WebKitWantsBalancedSetDefersLoadingBehavior": 0, "WebKitFrameFlatteningEnabled": 1, "WebKitDiagnosticLoggingEnabled": 0, "WebKitForceSoftwareWebGLRendering": 0, "WebKitSansSerifFont": "Helvetica", "AppleLanguages": ["en"], "WebKitSimpleLineLayoutDebugBordersEnabled": 0, "WebKitNetworkDataUsageTrackingEnabledPreferenceKey": 0, "WebKitExperimentalNotificationsEnabledPreferenceKey": 0, "WebKitPrivateBrowsingEnabled": 0, "WebKitUsesPageCachePreferenceKey": 1, "WebKitApplicationCacheDefaultOriginQuota": 26214400, "WebKitCursiveFont": "Snell Roundhand", "WebKitEnablePasswordEchoPreferenceKey": 1, "WebKitAcceleratedDrawingEnabled": 0, "WebKitSpatialNavigationEnabled": 0, "WebKitJavaScriptRuntimeFlagsPreferenceKey": 0, "WebKitStandardFont": "Times", "WebKitTelephoneParsingEnabledPreferenceKey": 0, "WebKitHistoryItemLimit": "1000", "WebKitStorageBlockingPolicy": 0, "WebKitNetworkInterfaceNamePreferenceKey": "", "WebKitInterpolationQualityPreferenceKey": 2, "WebKitCacheModelPreferenceKey": 0, "WebKitWebAudioEnabled": 1, "WebKitJavaScriptEnabled": 1, "WebKitApplicationCacheTotalQuota": 9223372036854775807, "WebKitUseLegacyTextAlignPositionedElementBehavior": 0, "WebKitPasswordEchoDurationPreferenceKey": 2, "WebKitUserStyleSheetEnabledPreferenceKey": 0, "AntialiasedFontDilationEnabled": 0, "WebKitEditableLinkBehavior": 0, "WebKitAudioSessionCategoryOverride": 0, "UserAgent": "CustomUserAgent", "WebKitLocalFileContentSniffingEnabledPreferenceKey": 0, "WebKitShowRepaintCounter": 0, "WebKitHiddenPageDOMTimerThrottlingEnabled": 0, "WebKitFixedFont": "Courier", "WebKitPageCacheSupportsPluginsPreferenceKey": 1, "WebKitUseSiteSpecificSpoofing": "0", "NSLanguages": ["en"], "WebKitJavaScriptMarkupEnabled": 1, "WebKitCSSRegionsEnabled": 1, "WebKitHyperlinkAuditingEnabled": 1, "WebKitAllowAnimatedImageLoopingPreferenceKey": 1, "WebKitLocalStorageEnabledPreferenceKey": 1, "WebKitWebArchiveDebugModeEnabledPreferenceKey": 0, "WebKitLowPowerVideoAudioBufferSizeEnabled": 0, "WebKitDeveloperExtrasEnabledPreferenceKey": 0, "WebKitAllowAnimatedImagesPreferenceKey": 1, "WebKitCSSCompositingEnabled": 1, "WebKitSerifFont": "Times", "WebKitQTKitEnabled": 0, "WebKitDefaultFixedFontSize": "13", "WebKitDOMTimersThrottlingEnabledPreferenceKey": 1, "WebKitLayoutIntervalPreferenceKey": -1, "WebKitAsynchronousSpellCheckingEnabled": 0, "WebKitPlugInSnapshottingEnabled": 0, "WebKitOfflineWebApplicationCacheEnabled": 0, "WebKitHistoryAgeInDaysLimit": "7", "WebKitAccelerated2dCanvasEnabled": 0, "WebKitDNSPrefetchingEnabled": 0, "WebKitSubpixelCSSOMElementMetricsEnabled": 0, "WebKitShouldRespectImageOrientation": 1, "WebKitDatabasesEnabledPreferenceKey": 1, "WebKitAllowFileAccessFromFileURLs": 1, "NSInterfaceStyle": "macintosh", "WebKitAuthorAndUserStylesEnabledPreferenceKey": 1, "WebKitAcceleratedCompositingEnabled": 1, "WebKitShowDebugBorders": 0, …, "WebKitFullScreenEnabled": 0, "WebKitWebSecurityEnabled": 1, "WebKitAlwaysRequestGeolocationPermission": 0, "WebKitAllowMultiElementImplicitFormSubmissionPreferenceKey": 0, "WebKitMaxParseDurationPreferenceKey": -1, "WebKitMinimumZoomFontSizePreferenceKey": 15, "WebKitXSSAuditorEnabled": 1, "WebKitEnableInheritURIQueryComponent": 0, "WebKitShrinksStandaloneImagesToFit": 0, "WebKitWebGLEnabled": 1, "WebKitBackForwardCacheExpirationIntervalKey": "1800", "WebKitAllowUniversalAccessFromFileURLs": 1, "WebKitUsesEncodingDetector": 0, "WebKitDefaultFontSize": "16", "WebKitPluginsEnabled": 1, "WebKitMinimumFontSize": "0", "WebKitCanvasUsesAcceleratedDrawing": 0, "WebKitMinimumLogicalFontSize": "9", "WebKitMediaPlaybackRequiresUserGesture": 1, "WebKitDefaultTextEncodingName": "ISO-8859-1"]
なるほど、なんかそれっぽいのが返ってきている!
すげーわかりづらいけど真ん中らへんに"UserAgent": "CustomUserAgent"
を見つけたので、これらはregisterDefaults
で登録された辞書の値だということがわかりました。
ということは、- volatileDomainForName:
で辞書を取得し、特定のキー(今回は'UserAgent')を削除し、- setVolatileDomain:forName:
で辞書を登録すれば行けそうな雰囲気を感じます。
ということでやってみました。
var webview = UIWebView.init() webview.stringByEvaluatingJavaScriptFromString("navigator.userAgent") // ""Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13C75"" // UAの登録 NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "CustomUserAgent"]) webview = UIWebView.init() webview.stringByEvaluatingJavaScriptFromString("navigator.userAgent") // "CustomUserAgent" // 登録されたUAの削除 var registeredDefaults = NSUserDefaults.standardUserDefaults().volatileDomainForName(NSRegistrationDomain) registeredDefaults.removeValueForKey("UserAgent") NSUserDefaults.standardUserDefaults().setVolatileDomain(registeredDefaults, forName: NSRegistrationDomain) webview = UIWebView.init() webview.stringByEvaluatingJavaScriptFromString("navigator.userAgent") // ""Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13C75"" <- 戻ってる!
ヒュー!
まとめ
NSUserDefaults
のregistrationDefaults
で登録した値を消したい時は- volatileDomainForName:
で辞書を取得し、特定のキーを削除し、- setVolatileDomain:forName:
で上書き登録し直す。
The following build commands failed: CompileStoryboard ProjectName/Base.lproj/LaunchScreen.storyboard
TravisCIでXcodeのプロジェクトをビルドしようとした時に発生したエラー。
まさかのStoryBoard
のコンパイル失敗。笑
結論、TravisCIのXcodeServer環境と手元の環境に差があるのが原因のようだったので、osx_image
を指定することでエラー回避。
language: objective-c osx_image: xcode7.2 script: make test
TravisCIのXcode環境は地獄だぜ・・ きっとXcodeServerの対応が大変なんだろうなぁと妄想しています。
余談
私はTravisCI上でxcodebuild
の出力をxcpretty
を利用して整形するようにしているのですが、出力だけをパイプで渡すとxcodebuild
がエラーを吐いてもCIがpassしてしまいます。
↓こんな感じ
** BUILD FAILED ** The following build commands failed: Check dependencies (1 failure) The command "make test" exited with 0. Done. Your build exited with 0.
この場合は下記のようにPIPESTATUSを引き継いで出力してあげると正しく動作してくれます。
test: xcodebuild -project ProjectName.xcodeproj | xcpretty -c && exit $${PIPESTATUS[0]} # Makefileの中なので$が2重