20190521のiOSに関する記事は5件です。

基礎から学ぶiPhoneアプリ開発

基礎から学ぶiPhoneアプリ開発

iPhoneやiPadで動くアプリ開発の手順書

XCode9対応

iOS SDKの機能について

Core OS

Core Services

機能・サービス名 説明
CFNetWork
Core Data
Core Foundation
Core Location
Core Media
Core Telephony
Core Foundation
Grand Central Dispatch
Mobile Core Service
SQLite
XML
アドレスブック
アプリケーション内購入
イベントキック
クイックルック
ブロックオブジェクト

Media

機能・サービス名 説明
AirPlay
AV Foundation
Core Animation
Core Audio
Core MIDI
Core Text
Image I/O
OpenAL
OpenGL ES
Quartz
アセットライブラリ
ビデオ
メディアプレイヤー

Cocoa Touch

機能・サービス名 説明
AirPrint
iAd
iTunes ファイル共有
Mapキット
Peer-to-Peer通信
UIKit
アドレスブックUI
アプリケーション内メール送信
イベントキットUI
ジェスチャー認識
プッシュ通知サービス
マルチタスク
ローカル通知

制作チーム:サンストライプ
http://sunstripe-main.jp/
(月1WEBコンテンツをリリースして便利な世の中を作っていくぞ!!ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中!!)
地域情報 THEメディア
https://the.themedia.jp/
(THE メディア ボランティア編集ライター募集中!!)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

アプリ開発で使う mitmproxy 4.0 のコマンド一覧

mitmproxy 4.0チートシート

  • アプリ開発でよく使うコマンドをまとめた
    • 大きく操作が変わったversion 4での内容です
  • 基本的な操作 q, tab, enter, j, k, ctr + d, shift + g, gg は除く

コマンド一覧みたい

?

flow list をフィルタリングしたい

f

並び替え(sort, order by)したい

o

画像のみをフィルタリングしたい

# fを押して
f

# : set view_filter= が表示されるので、下記を入力
~a jpg

POST(Method)のみをフィルタリングしたい

f
~m POST

Content-typeでフィルタリング

f
~t json

flow list をコピーしたい

  • Altを押したまま選択
  • macだとfnを押したまま選択

flow listを消したい

z

curlコマンドに変換(コピー)したい

# :を押してコマンドプロンプトにして
:

# 以下を入力でクリップボードにcurl形式でコピー
# @focusで表示中の内容をコピー
export.clip curl @focus

常に一番下に新しい通信を表示したい(followingモード)

F (shift + f)

# 解除は再度F
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Firebase Analyticsの調査(画面の自動追跡)

Firebase Analyticsへの移行に向けて

iOS/Androidアプリ向けGAの終了の通知があり、お早めに Firebase SDK でアプリをトラッキングするように移行していただけますようお願いいたします。とアナウンスがあったころから、携わっているiOSアプリのプロジェクトでもFirebase Analyticsへの移行に向けての調査を進めており、調査でわかったことをまとめていきたいと思います。

画面の自動追跡

Firebase Analytics(以下「FA」)が、GAと大きく違う点に自動の画面追跡機能があります。
GAではviewDidAppearなどのタイミングで、専用のメソッドをコールして手動でスクリーン名を送信していましが、FAでは画面追跡のイベント(screen_viewイベント)が自動で送信されます。
※FAでは、現在フォーカスされているUIViewControllerのクラス名など、アプリケーション内の画面に関する一部の情報を自動的に追跡しています。

なお、送信されたscreen_viewイベントの値はFirebase ConsoleのAnalyticsのEventsで
確認できます。(※以下の画像をご参照ください。)

<自動送信された画面のUIViewControllerクラス名>
FAスクリーンクラス.png

ちょっと表示が切れていますが、上記の画像を見ると、ViewControllerのクラス名が自動的に送信され、スクリーンクラスに表示されているのがわかります。

画面自動追跡の設定手順

参照:Get Started with Google Analytics for Firebase for iOS

上記を参照し、進めていけばOKです。手順の大まかな方法は、以下の通りです。(2019/5/20時点)

1.'Firebase/Analytics'をpodでインストールする

pod 'Firebase/Analytics'

2.application:didFinishLaunchingWithOptions:でFirebaseライブラリの設定を行う

import Firebase

// (途中省略)

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()
    // (途中省略)
    return true
}

注意: 既存のプロジェクトでスクリーンクラスが(not set)になる

新規プロジェクトでFAを導入する場合は、上記の設定手順で問題なく画面が自動追跡され、スクリーンクラスがfirebase consoleでも表示されたのですが、既存プロジェクトにFAを導入したところ、firebase consoleで表示されるスクリーンクラスが(not set)になる現象が発生しましたので、対応方法をまとめます。

FA_not_set.png

原因がわからずいろいろ設定を見直したところ、以下のInfo.plistの項目が原因でした。

<key>FirebaseAutomaticScreenReportingEnabled</key>
<false/>

既存のプロジェクトでFirebase Analyticsは利用していなかったのですが、Firebaseの別のサービスFirebase Cloud Messagingを利用していました。

どの過程でFirebaseAutomaticScreenReportingEnabledの項目がInfo.plistに設定されたのか、なかなか追えなかったのですが、FirebaseAutomaticScreenReportingEnabledの項目を除去するかtrueを設定すると、画面の自動追跡が有効になりFirebase consoleでスクリーンクラスが表示されるようになります。
(新規プロジェクトにFAを導入した際は、Info.plistのFirebaseAutomaticScreenReportingEnabledの設定が無かったので、画面の自動追跡を行う場合は不要かと思います。)

今回はFirebase Analyticsの画面自動追跡の内容でしたが、引き続き調査した内容を今後もQiitaにまとめていく予定です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Safariの<input type="file">で問題が繰り返し起きるときの対応

はじめに

ファイルアップロードは、かなり鉄板機能なので実装することが多いのですが、ハマりかけたのでログに残しておきます。

エラーまでの経緯

ファイルアップロードのソースは、雰囲気こんな感じです。

inputタグをそのまま使うとダサいので、style="display: none"にして、その代わりにボタンやフォームのクリックイベントでinputタグのクリックイベントを発火します。

<template>
  <!-- 上は省略 -->
  <div class="text-xs-center">
    <img :src="imageUrl" height="200" v-if="imageUrl"/>
    <v-text-field color="primary" label="Select Image" @click='pickFile' v-model='imageName' prepend-icon='attach_file'></v-text-field>
    <input
     type="file"
     style="display: none"
     ref="image"
     accept="image/*"
     @change="onFilePicked"
    >
  </div>
  <!-- 下も省略 -->
</template>

<script>
export default {
  data () {
    return {
      imageName: '',
      contentType: '',
      imageUrl: '',
      imageFile: ''
    }
  },
  methods : {
    pickFile () {
      this.$refs.image.click ()
    },
    onFilePicked (e) {
      const files = e.target.files

      if(files[0] !== undefined) {
        this.imageName = files[0].name
        this.contentType = files[0].type  // contentType: image/jpegとか
        if(this.imageName.lastIndexOf('.') <= 0) { return }

        const fr = new FileReader ()
        fr.readAsDataURL(files[0])
        fr.addEventListener('load', () => {
          this.imageUrl = fr.result
          this.imageFile = files[0] // this is an image file that can be sent to server...
        })

      } else {
        this.imageName = ''
        this.imageFile = ''
        this.imageUrl = ''
      }
    }
  },
  /** いろいろ省略 **/
}

</script>

開発が一段落し、自分のiPhoneでぽちぽちやっていると、こんな現象に遭遇しました。

問題が起きたため、このWebページが再読込されました。
XXXXXXXXで問題が繰り返し起きました。

調べた

Safariでは、display:noneに問題があるらしいです。なので、『inputタグはdisplay:noneではなく、divで囲んでheightとwidthを0にせよ』とのことでした。

<template>
  <!-- 上は省略 -->
  <div class="text-xs-center">
    <img :src="imageUrl" height="200" v-if="imageUrl"/>
    <v-text-field color="primary" label="Select Image" @click='pickFile' v-model='imageName' prepend-icon='attach_file'></v-text-field>
    <div class="hiddenfile"> <!-- ←これで囲む -->
      <input
       type="file"
       ref="image"
       accept="image/*"
       @change="onFilePicked"
      >
    </div>
  </div>
  <!-- 下も省略 -->
</template>

<script>
/** 変更なし **/

</script>
<style scoped>
.hiddenfile {
  width: 0px;
  height: 0px;
  overflow: hidden;
}
</style>

う〜ん何故だろう、、、
むかしからdisplay:noneが常識かつ定石だと思っていましたら、Safariさんは違ったようです。

めでたし。

参考記事

Safari input='file' doesn't work

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WebViewとネイティブのメリットデメリット

App内で動作する簡易ブラウザ(WebView)と通信からUIまでアプリ内で完結するネイティブアプリのメリットデメリットをまとめてみました。

■WebViewのメリット・デメリット

メリット

  • コストが安い
    Web上にコンテンツがあり、それを流用したい場合、新規で開発することなく同じコンテンツを表示できます。

  • アプリストアへの申請・審査の不要
    ネイティブアプリの申請や審査が不要になります。
    ※ただし、部分的なWebView表示の場合ネイティブと変わらないので審査は必要です。

  • アプリアップデートの不要
    アプリの保守をする必要がないため、アプリ自体のアップデートがありません。
    ※仕様が変更された時は、アプリの動作を変更する可能性があるため、一概ではないです。

デメリット

  • 課金ができない
    Apple Store審査ガイドラインの規約違反になり、リジェクトされる恐れがあります。
    ※Webブラウザでの課金は可能(リンクをブラウザへ飛ばす必要あり)
    引用:Apple Store審査ガイドライン:3.1.1 App内課金

  • レスポンシブ対応
    画面解像度に応じたUI設計の対応が必要。
    Webの表示をそのまま、アプリに適応させると表示崩れが起こる可能性がある。

  • 脆弱性

    1. 自社以外の外部アクセス

      URL直打ちで、自社ではないサイトにアクセスできる場合、悪用される恐れがある。
      外部アクセスできるサイトに制限を設ける必要がある。

    2. 端末内のファイルストリームにアクセスできる

      「file://」で始まるURI(※URLではない)でアクセスすることで、端末内部のファイルにアクセスすることができる。
      アクセスログからユーザー情報が漏洩されてしまう。

    3. iOSは、Cookieを保存しない

      アプリが終了するとCookieが消えるので、永続化する必要がある

    4. XSSの恐れ

      攻撃スクリプトを入力できてしまう。
      サニタイジング(無害化)する必要がある。

  • 通信エラー場合の表示
    通信エラー場合のWebView画面を表示する前に、レスポンスチェックを行い、ネイティブの別画面を表示させる。
    WebViewは通信した結果の表示なので、真っ白になったり、URLエラーになったりしてUI的に作りが悪い。

  • 環境によっては表示が遅い
    Web通信が伴うため、通信環境によっては表示が遅い場合があります。

  • 導線が不可能
    WebViewの誘導はできない。
    alt

■ネイティブ画面のメリット・デメリット

メリット

  • Webではできない画面設計・操作設計ができる
    アプリ内のUIを使用するため、自由に画面設計を行うことが可能

  • 導線設計が可能
    アプリに誘導できる

  • セキュリティ
    URL直打ちではないため、外部のサイトへアクセスさせることはないです。

デメリット

  • コストが高い
    iOS / Androidの開発者が必要
    開発言語が異なるため、それぞれの開発者が必要

  • アプリストアへの申請・審査
    ネイティブアプリの申請や審査が必要です。

  • アプリアップデートが必要
    保守でアプリ修正があった場合は、アップデートが必要

  • 課金
    App内課金を(30%)手数料(30%)が発生する

引用

https://appbu.jp/webapps-nativeapps
https://ja.developer.box.com/docs/android-security-guidelines
https://appkitbox.com/knowledge/android/20130819-84
https://teratail.com/questions/100872
https://mexess.blog/2018/08/03/post-304/
https://qiita.com/noboru_i/items/240ffcb2036f3b5cbc3b
https://qiita.com/noboru_i/items/bc39d95638e9e55437fa#cookie%E3%81%AE%E8%A8%AD%E5%AE%9A
https://qiita.com/i_nak/items/be0fac91bdc68aa165db
https://backapp.co.jp/blog/11594/
https://support.ebis.ne.jp/search_service/15033/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む