面白きことは良きことなり

拙く未熟なiOSエンジニアの備忘録と戯言

拡張子"xip"を調べてみた

Xcode8のbeta版配布時、サイトからDLしてくると.xipという拡張子でファイルを取得してくる。
特に気にせず、ダブルクリックで開けていたのできにしていなかったが、改めてどういう形式なのか気になり調べてみた。

terminalでman xipと打つと下記のように説明がある。f:id:aryzae:20160920132418p:plain

A XIP file is an analog to zip(1), but allows for a digital signature 
to be applied and verified on the receiving system, 
before the archive is expanded. 

When a XIP file is opened (by double-clicking), Archive Utility will 
automatically expand it (but only if the digital signature is intact).

【意訳(自動翻訳+修正)】

XIPファイルはアナログなZIP(1)ですが、アーカイブが展開される前に
システム上でデジタル署名が適用され検証されます。 

(ダブルクリックして)XIPファイルを解凍した際、アーカイブユーティリティは
自動的にそれを展開していきます(ただし、デジタル署名が破損している場合のみ)。

つまり、xip = zip + digital signature(デジタル署名) という認識でよさそう。
zip形式だけど、怪しくないファイルだよ!開いても問題ないよ!ってとこかな。

ちなみに発音はどうなるんだろう?
ズィップ?エグズィップ?

iOS10でアプリ起動時にアプリのアイコンが拡大表示される現象

iOS10でアプリ起動時(Launch Screen)にアプリのアイコンが拡大表示される現象に遭遇したのでまとめときます。

<発生条件>
  • iPadのみ (手持ちのiPhone6sでは発生しなかった)
  • アプリのprojectにLaunch Screenを設定していないでBuildしている

現象の見た目は下記のような感じ
f:id:aryzae:20160920141217g:plain


<解決方法>

・projectにLaunch Screenを設定しましょう。
 (今時よっぽどのことがない限り、設定していないことはないので遭遇自体レアでしょうが・・・)


iOS9以前であれば、Launch Screenが設定されていない時は黒画面が表示されていましたが、iOS10で挙動が少し変わったようですね。
また、iPhoneで試した際は、Home画面が表示されていました。(透明なLaunch Screenが表示されていたという方が適切かも?)

UIImageのRenderingModeのサンプルコード

1枚の画像で色だけ変えて使いまわしたいと思ったものの、
色の数だけ画像を用意するのも大変だし、動的に色を変えるのも難しいと思い、
いい方法がないか調べたところ、UIImageにRenderingModeなるものが存在することを今更知った。

今回下記画像を用意し、実際に簡単なサンプルコードを書いた。
画像は蝶々の部分が白色で他は透過処理してある100*100pixelのpng画像。
(見やすくするため、画像の背景をタグで灰色指定している。)


f:id:aryzae:20161025011928p:plain

// Swift3
        // 白背景だと画像が見えなくなるため、灰色背景に変更
        view.backgroundColor = .gray
        
        // 比較用に元画像をそのままUIImageViewで表示 
        originalImageView.image = UIImage(named: "original")
        
        // RenderingModeでtemplate化
        let image = UIImage(named: "original")?.withRenderingMode(.alwaysTemplate)

        // RederingModeでTemplate化した画像を入れ、tintColorで色指定
        leftImageView.image = image
        leftImageView.tintColor = .red
        
        centerImageView.image = image
        centerImageView.tintColor = .green
        
        rightImageView.image = image
        rightImageView.tintColor = .blue

表示結果

f:id:aryzae:20161025011910p:plain
簡単な処理でこのように扱えるので便利。

ATS(App Transport Security)を"Xcode8 GM seed"+"iOS10 GM seed"でテストしてみた

iPhone7が発表され、Xcode8やiOS10のGM seedも来ましたね。
いつものごとく、テストしてみました。
実質リリース版と同じなのでテストとしてはラストになると思います。

テスト方法

テスト方法は、プログラムの使い回しで基本今までを踏襲していますが、下記赤字が変更点となります。

  • iOS10は、iOS10.0.1 GM seedを使用
  • iOS9は、iOS9.3.5を使用
  • ATSは、最初Xcode7BuildのipaとiOS9の組み合わせで発動していたので、Xcode7BuildとXcode8Buildで違いでるか比較
  • NSAllowsArbitraryLoadsInWebContentの設定で挙動がどう変わるか確認
  • HTTPSは、URLにhttps://www.apple.com/を使用
  • HTTPは、URLにhttp://www.yahoo.co.jp/を使用
  • HTTP(LAN)は、MAMPを使用してURLにhttp://192.168.0.12/を使用
  • UIWebView / WKWebView / NSURLSession / SFSafariViewController の4つで比較
  • キャッシュ?のようなものが残り不自然な挙動があったため、テスト毎にテストアプリをインストールし直して実行
  • ATSは表のKeyのみを設定
  • 補足としてnoneとなっているものはKeyを削除している状態のこと

結果

Xcode7.3.1 Build

f:id:aryzae:20160912044200p:plain

Xcode8.0 GM seed

f:id:aryzae:20160912044204p:plain

備考

下記Keyが候補に出てこなかったけど、実装されているのだろうか・・・

  • NSAllowsArbitraryLoadsInMedia
  • NSAllowsLocalNetworking
  • NSRequiresCertificateTransparency

AppleでKeyを確認するとXcode nameが(none)になっているので、補完入力では出ないけど、Key自体は有効かもしれません。(テスト結局一切やれてない…。)
が、NSAllowsArbitraryLoadsInWebContentXcode nameも(none)になっているあたりリファレンスの更新がされていない可能性が…ちゃんとAllows Arbitrary Loads in Web Contentって出るのに。
NSRequiresCertificateTransparencyに関してはNSExceptionDomainsの中に含まれるようになってました。

===関連記事===

Xcode8.0 beta の記事

aryzae.hatenablog.com

Xcode8.0 beta2 の記事

aryzae.hatenablog.com

Xcode8.0 beta3 の記事

aryzae.hatenablog.com

Xcode8.0 beta4 の記事

aryzae.hatenablog.com

Xcode8.0 beta5 の記事

検証していないのでなし。

Xcode8.0 beta6 の記事

aryzae.hatenablog.com

Googleとかで検索するとbeta違いの記事が出てきて見苦しいから1ページにまとめようか思案中。

AVAudioPlayerで音が鳴らなかった問題

結論:インスタンスはプロパティで保持しろ

do {
    let player = try AVAudioPlayer(contentsOfURL: fileUrl)
    player.volume = 1.0
    player.numberOfLoops = 0
    guard player.prepareToPlay() else {
        return
    }
    player.play()
} catch let error as NSError {
    print(error.localizedDescription)
}

こんな処理を書いて音が鳴らない…なんで?としょうもないところで悩んだ。
シミュレーターだから?実機でもだめだ…ファイルパスは合ってる…とか調べて悩んでたけど、ググったらプロパティで作ったら鳴ったとかあった。
試したら見事に、その理由。

処理して音が鳴る前にローカル変数のインスタンスが破棄されてるみたいね。
プロパティを減らしてメモリ消費量を抑えるように心がけた結果、裏目にでた感じ。