iOSアップデートはいつだって後悔
衝動的にiPhoneのアプリ更新をまとめて片づける休日の午後。
  更新内容のほとんどに、iOS13への対応が含まれている模様である。
  
  「どうせなら時間のあるときに」と、“後悔するのを覚悟”でiOSも13へアップデートする。
  
  後悔の念は思ったより早く来た。
  トカチニッチの記事用に制作途中だったthree.jsをsafariで走らせるも全く動かないのだ。
  
  慌てて“納品済み”のプログラムを確認するが、そちらは大丈夫な様子。
  安定性を考慮した「OrbitControls」のみのthree.jsは動くのに、スマホのジャイロ機能を用いる「DeviceOrientationControls」が含まれると動かない。
  ※この記事のプログラムも動かなくなった。
  
  iOS12.2で必要になった「モーションと画面の向きのアクセス」がsafariの設定から消えているのが原因なのだろうと調べるとすぐに解決方法が見つかった。
  いつも助けてくれる先人たちに感謝の気持ちを伝えたい…。
今回作ったもの
iOS13+のsafariではアプリが求める「“動作と方向”へのアクセス」を許可する方式になるようだ。
  
  ただ「UserAgentを調べて」とか「バージョンで判断して」の類は、やりたくないし、得体の知れない判定を最初に持ってくるのは気乗りしない。
  シンプルに、「ジャイロが動いたらそれで良し」→「ジャイロが動かなかったらiOS13+用の判定を使う」方法にしたい。
実際の判定部分
//ジャイロセンサー確認
var isGyro=false;
if((window.DeviceOrientationEvent)&&('ontouchstart' in window)){
	isGyro=true;
}
//PCなど非ジャイロ
if(!isGyro){
	setCanvas();
//一応ジャイロ持ちデバイス
}else{
	//ジャイロ動作確認
	var resGyro=false;
	window.addEventListener("deviceorientation",doGyro,false);
	function doGyro(){
		resGyro=true;
		window.removeEventListener("deviceorientation",doGyro,false);
	}
	//数秒後に判定
	setTimeout(function(){
		//ジャイロが動いた
		if(resGyro){
			setCanvas();
		//ジャイロ持ってるくせに動かなかった
		}else{
			//iOS13+方式ならクリックイベントを要求
			if(typeof DeviceOrientationEvent.requestPermission==="function"){
				//ユーザアクションを得るための要素を表示
				cv._start.show();
				cv._start.on("click",function(){
					cv._start.hide();
					DeviceOrientationEvent.requestPermission().then(res => {
						//「動作と方向」が許可された
						if(res==="granted"){
							setCanvas();
						//「動作と方向」が許可されなかった
						}else{
							isGyro=false;
							setCanvas();
						}
					});
				});
			//iOS13+じゃない
			}else{
				//早くアップデートしてもらうのを祈りながら諦める
				isGyro=false;
				setCanvas();
			}
		}
	},300);
}
「setCanvas()」でthree.jsの描画が始まるが、isGyroがtrueなら「DeviceOrientationControls」を、falseなら諦めて「OrbitControls」を使う。
  まずdeviceorientationのイベントリスナが動くか否かをsetTimeoutで数秒後に判断(例では300ミリ秒)。
  
  deviceorientationで値が取得できなかった場合のみ、iOS13+方式と認定して「“動作と方向”へのアクセス」の許可ダイアログを出す流れ。
  許可ダイアログを出すにはユーザアクションが必要なので、タッチイベントを得るための要素(例では「.canvas_start」)を非表示で用意しておく。
  
  とにかく何だか気持ち悪い判定は極力動かしたくない…ただそれだけ。
  本来の、もっと良い方法があると思うのでそちらを使ってください。
  
  ほぼ、iOS12.2のときに感じた「こうなればいいのに」という理想に近いが、許可要求のダイアログを表示するにはタッチなどユーザアクションが必要なのが惜しい。
  「カメラ起動」の許可要求はユーザアクションなしでもそのまま出せるのに…Appleの考えるセキュリティの奥深さに理解が追い付かない。
使用したパノラマ画像は大樹町の紅葉スポット「坂下仙境」。そろそろ色どり溢れる絶景で来訪者を楽しませてくれるだろう。
※熊には充分気を付けましょう!
【PR】 Amazonで「Three.js」を探す!



          
          
          
          
          
          
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                




