uka.apple のすべての投稿

独創アプリ開発日記 70日目 alert, confirm, prompt

今日も引き続きテキスト漫画のガワネイティブアプリ化です。

ガワネイティブアプリでWebを表示するのに多用されるWKWebViewですが、JavaScriptのalert,confirm,promptに関してはデフォルトで何も表示してくれません。

alert,confirm,promptのダイアログを表示させるには UIAlertAction で適切に処理してあげる必要があります。

 

と言っても定型でほぼ処理コードは決まっているため、以下のように書いてあげれば大丈夫です。Swift4のコードです。


import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {

    private var _webView : WKWebView!
    〜略〜
    override func viewDidLoad() {
        super.viewDidLoad()
        〜略〜
        _webView.uiDelegate = self
        〜略〜
    }

    func webView(_ _webView: WKWebView, runJavaScriptAlertPanelWithMessage alert: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        
        let alertController = UIAlertController(title: "", message: alert, preferredStyle: .alert)
        let otherAction = UIAlertAction(title: "OK", style: .default) {
            action in completionHandler()
        }
        alertController.addAction(otherAction)
        self.present(alertController, animated: true, completion: nil)
    }
    
    func webView(_ _webView: WKWebView, runJavaScriptConfirmPanelWithMessage confirm: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        
        let alertController = UIAlertController(title: "", message: confirm, preferredStyle: .alert)
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
            action in completionHandler(false)
        }
        let okAction = UIAlertAction(title: "OK", style: .default) {
            action in completionHandler(true)
        }
        alertController.addAction(cancelAction)
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: nil)
    }
    
    func webView(_ _webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
        
        let alertController = UIAlertController(title: "", message: prompt, preferredStyle: .alert)
        
        alertController.addTextField { (textField) in
            textField.text = defaultText
        }
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) in
            completionHandler(nil)
        }))
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            if let textField = alertController.textFields?.first?.text {
                completionHandler(textField)
            } else {
                completionHandler(defaultText)
            }
        }))
        self.present(alertController, animated: true, completion: nil)
    }    
    〜略〜
}

 
 
 
    _,,..,,,,_
   / ,’ 3  `ヽーっ
   l   ⊃ ⌒_つ
    `’ー—‐””'” 
 

独創アプリ開発日記 69日目 キーチェーンアクセス

引き続き、テキスト漫画サイトのガワネイティブアプリの作成を行っていました。

今日は、昨日諦めたキーチェーンアクセス処理を頑張って実装し、アプリ再インストールの場合でもユーザ識別用のIDを復元することが出来るようになりました!!

処理の流れとしては

1. UserDefaultsに保存したIDを確認

2. 1でIDが取得できればそれを使う

3. 1でIDが取得できなければキーチェーンからIDを取得

4. 3でIDを取得できればそれを使う。UserDefaultsにIDを保存。

5. 3でIDが首都できなければIDFVを取得して、それをIDとしてUserDefaultsとキーチェーンに保存

としました。

UserDefaultsはアプリ再インストールで消えてしまう情報、キーチェーンはアプリ再インストールでも消えない情報です。

上記の流れにしておけば、もしアプリが再インストールされた場合でも 1 > 3 > 4 の流れでIDが復元できますし、アプリが再インストールされていない場合はUserDefaultsから素早くIDを取得出来ます。

キーチェーンアクセスを行うライブラリは色々ありますが、1つの文字列を同一アプリ内で保存して利用するだけなので、このURLのベージ下部のswift4用コードを参考に最小限での実装としました。

iOSで使う場合は、いくつかMacOS用のコードでエラーが出るので気を付ける必要がありますが、数行だけですので簡単に直せるかと思います。

上記URLのコードがビダァァァン!!!!と私の使用用途にハマりました。

 
 
 
    _,,..,,,,_
   / ,’ 3  `ヽーっ
   l   ⊃ ⌒_つ
    `’ー—‐””'” 
 

独創アプリ開発日記 68日目 アプリへのidfv保存

引き続き、テキスト漫画サイトのガワネイティブアプリの作成を行っています。

今日は、昨日取得したユーザを識別するID(idfv)をアプリで保存するようにしました。

基本的にidfvは変わらないものなのですが、過去、iOSでアプリをアップデートするとidfvが変わってしまうというバグがあったらしいです。そのため、念のため1度取得したidfvはアプリにデータとして保存し、2回目以降は保存したデータからidfvを取得しようと思います。

こうすることで、もし再度バグなどが発生してidfvが変わってしまっても大丈夫になります。

コードは以下のようになりました。

struct Constants {
    enum User : String {
        case idfv
    }
}
〜 略 〜
// デバイスの識別
let idfv : String!
if UserDefaults.standard.object(forKey: Constants.User.idfv.rawValue) != nil {
    // UserDefaultsにある場合、それを使用
    idfv = UserDefaults.standard.string(forKey: Constants.User.idfv.rawValue)
} else {
    // UserDefaultsにない場合、IDFVを取得
    idfv = UIDevice.current.identifierForVendor!.uuidString
    // idfvは36文字だが、念のためハイフンをのぞいて32文字以上あれば正常に取得できたと判断して保存
    if (32 <= idfv.count) {
        // 保存
        UserDefaults.standard.set(idfv, forKey: Constants.User.idfv.rawValue)
        // 削除する場合は以下
        //UserDefaults.standard.removeObject(forKey: Constants.User.idfv.rawValue)
    }
}

尚、アプリを再インストールした場合(正確には同一ベンダーのアプリが全てアンインストールされた場合)もidfvが変わってしまいますが、その場合はUserDefaultsも消えてしまうのでどのみちidfvは保持出来ません。

UserDefaultsとは別に、Keychain Servicesというものがあり、こちらを使えばアプリをアンインストールしても値を維持出来そうです。一瞬、これを利用しようかと思いましたが、

めんどうそうなので諦めました。

                  ,!  \  
           ,!\          !    \       
         i  \         l      \,,..__  
          ,i′  ,\___,,--―l       \::゙'冖ーi、、  
        i     :;\::::::::::..l              `'‐、、  
       /__,..;:r---―-、,..__.     ,;'il:;}          .;:::`L__  
   ,.:f''""゙゙゙´          、 ̄ヽ,//           ...::::::l;;;:;;::::  
  _/       ......  、   \//、            ::::::::リ;;:::::::::....  
//       ......:;::::::::::::. ヽ、\ ゙ヽ  ヘ    ●      ....:::::::::i';;;;::::::::::::  
;;/    ::::::::::::;;;;;ノ ̄\:: 〉 〉゙'、 `ヽ_ノ       ......:::::::.;;;:ノ:;;;:::::::::::::  
/    ..::::、__;;ノ;;;`ヽ_/: / /⌒)メ、_ノ/         .....:::::;;;/;;;:::::;;:::::::::  
     ..:::イ;;.ヽ::;;;;;;;;;(__ノ /'"..:::::::::::::/  ...............:::::::::::;;;,;ノ;;::::::::::::::::  
     :::::::l;;;;;;;;;\;;;;;;;,.(__ノ;.;:.\:::::::::/::::::::::::::::::::::::::::;;;;;/;:::::::::::::::::  
    ::::::::,!::;;;;;;;;;;:.`゙'-、、  ::: \_/::::::::::;;;___,.;-―''"::::::::::::::::::::::::  
   ..::::::::::,!;;;;;:;;;;;:::;;;;;:::;;;;;;`゙ ̄'''冖''―--―'";;;;;;;;;::::::::::::::::::::::::: 
 

独創アプリ開発日記 67日目 アプリ判定

今日はアプリからテキスト漫画のサイトを見た場合のみ、ガワネイティブアプリ専用のデザインに変わるようにしました。

仕組み的にはアプリからアクセスする場合にiOSのidfvという識別IDをURLに付与して、それを元にcssを切り替えています。

以下のようなコードで取得します。

let idfv : String = UIDevice.current.identifierForVendor!.uuidString

ご覧の通り、スマホでアクセスしてもsafariからだと従来のデザインで表示されます。

 

よし、これでアプリ審査通る・・・か?Webサイトをそのままアプリ化するとreject食らうっていう話だけど、これなら良い筈だ・・・

  
                |
     Apple様       ||
      ( ^+^)    .|||
    /     \    |||| Reject!!
   / /\   / ̄\ ||||      .’  , ..
 _| ̄ ̄ \ /  ヽ \从// ・;`.∴ ’     
 \ ̄ ̄ ̄ ̄ ̄ ̄ \__) < ,:;・,‘  
  ||\            \     ’ .’ , ..
  ||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄
  ||  || ̄ ̄ ̄ ̄ ̄ ̄ ̄||
     .||              || 

独創アプリ開発日記 66日目 アプリ判定

今日は、アプリかどうかによってcssを切り替える作業を行いました。

phpでユーザーエージェント $_SERVER[‘HTTP_USER_AGENT’] にiPhone, iPad, iPodの文字が含まれているかどうかでひとまずは判定しています。

iPhoneやiPad,iPodでテキスト漫画のサイトにアクセスすると、cssが切り替わるようになりました。

Android?

知らない子ですねぇ・・・

    ∧ ∧___ 
   /(*゚ー゚) /\
 /| ̄∪∪ |\/
   |アンドロイド|/
     ̄ ̄ ̄ ̄

独創アプリ開発日記 65日目 css下準備

今日は、ガワネイティブアプリを作成するための準備としてデザイン部分をcssファイルにまとめていました。

ガワネイティブアプリはPC用のサイトと同じページを利用しますが、デザインだけはアプリ専用にします。

デザイン部分をcssファイルにまとめることで、PC用とガワアプリ用のCSSを手軽に切り替えられるようにします。

     ∧∧
    (,,゚ー゚)
  ~(___ノ

↑ちびしぃです。特に意味はありません。

独創アプリ開発日記 64日目 続改良

今日もテキスト漫画のサイトに手を入れていました。

・今日やったことその1

複数の半角スペースをWebで表示しようとすると、1つの半角スペースにまとまってしまうのはWebの仕様ですが、この仕様はテキスト漫画を作成する場合に混乱を招きます。

そこで、テキスト漫画を表示する際は半角スペースを特殊文字にして、1つにまとまらないようにしました。

・今日やったことその2

テキスト漫画のサイトとWordpressのサイトに同じテキスト漫画を表示した場合、微妙に表示が異なっていることに気づきました。調べたところ、lang指定が原因でした。

<html lang=”ja”>

これで表示変わっちゃうんだね・・・この対策も行いました。

・今日やったことその3

フォント指定のタグを、標準でコピーするようにしました。

↓こんなのです。

<p lang=”” style=”font-family:’MS PGothic’,’MS Pゴシック’,sans-serif;font-size: 12pt; line-height:normal;”>
・・・テキスト漫画部分・・・
</p>

これで「コピーする!」のリンクからコピペするだけで手軽に使えます。

もう完璧だと思います。

 ∧_∧     
 ( ・ω・)=つ≡つ 
 (っ ≡つ=つ=つ 
 /   ) バババ
 ( / ̄∪ 
ボコボコにしてやんよ。

独創アプリ開発日記 63日目 それぞれの環境

昨日からAAズレの対策を色々検討していましたが、よくよく考えたら問題ありませんでした。

スマホ使う人:スマホで作ってスマホで使う → ズレない
PC使う人:PCで作ってPCで使う → ズレない
私のような開発者:PCやスマホで作ってスマホやPCやいろんな環境で確認する → 色々ズレる

うん、多分PCやスマホ混在(WinやMac混在)で使う人少ないよね。

既に解決してた。

      ∧_∧ 
     _(  ´Д`) 
    /      ) 
∩  / ,イ 、  ノ/   
| | / / |   ( 〈 ∵. 
| | | |  ヽ  ー=- ̄ ̄=_、 
| | | |   `iー__=―_ ;,
| |ニ(!、)   =_二__ ̄_=;,
∪     /  /
     /  / 
    / _/  
    ヽ、_ヽ 
 

いや、でも自分以外の不特定多数に見てもらいたいから、いろんな環境で見られるよなぁ。全然解決してないわ。でも使う人がきっとなんとか解決方法を編み出してくれるはずだ。多分。

  ワケ
  ∧_∧
 ( ・∀・)
⊂ ⊂  )
 < < <
 (_(_)

独創アプリ開発日記 62日目 AAずれ

今日もテキスト漫画サイトのアプリ化について作業をしていました。このサイトのiPhoneアプリを出すにあたり避けられない問題として、AAずれがあります。

iOSとWindowsって、当たり前だけどフォントが違うから、AAずれるんだよね・・・

で、このAAズレの対策を色々検討していましたが、結局これといった決定的な策が出てきませんでした。

Windows環境用:

      ∧_∧      ∧_∧
     _( ´∀`)    (´∀` )
  三(⌒),    ノ⊃    ( >>1 ) 
     ̄/ /)  )      | |  |
    . 〈_)\_)      (__(___)
 糞スレは・・

Mac/iPhone用:

         ∧_∧      ∧_∧
     _( ´∀`)  (´∀` )
      三(⌒),    ノ⊃       ( >>1 ) 
        ̄/ /)  )       | |  |
    . 〈_)\_)     (__(___)
 糞スレは・・

どうしよ・・・

独創アプリ開発日記 61日目

今日もテキスト漫画のサイトに手を加えていました。

今回は、テキスト漫画の並び順「更新順」「人気順」や、表示しているページ数、さらにログイン中に指定できる「自分専用のみ表示」のチェックボタンをセッションに保存して記憶するようにしました。

前は、例えば「更新順」で3ページ目を出しておいて、そのページのテキスト漫画を変更後、元の画面に戻ると「人気順」で1ページ目に戻ったりしましたが、ちゃんと元の「更新順」で3ページ目に戻るようになりました。

細かいところですが使いやすくなりました。

    ←
     ∧_∧
   ∧_∧・ω・`) ↑
↓ ( ・ω・`)・ω・`)
  く| ⊂)ω・`)
   (⌒ ヽ・`)
   ∪ ̄\⊃