2025年7月31日木曜日

iOS で ajax が動かない

$.ajaxで undefined なエラー?

iOS 用のアプリ(WEBアプリ)で、ログイン後にデバイストークンを登録しようとして、以下のような構成にしてました
login.js - IDやパスワードを調べてログインするまでをクラス化したもの
device_toiken.js - デバイストークンをDBに登録するためのクラス
ここで、デバイストークンの登録が必要なのはデバイスがスマホアプリの時だけです。
サービスはスマホに PUSH 通知するけど、WEB PUSH は使わないんで。
なので、login.js と device_token.js は、独立してて相互通信をする必要はないのよね。

カスタムイベントを用意する

そこで、login.js はログインが成功したら、独自に作ったカスタムイベントを発行するんです。
こんな感じ。

    // ログイン完了イベントを発行する
    window.dispatchEvent(new CustomEvent(LOGIN_EVENT_NAME, {
        detail: {
            login_id: login_id,
            device_type: device_type
        }
    }));

受け取り側の device_token.js では、イベントを待機したらデバイストークンを取得してサーバに登録します。
こんな感じです。

    // ログイン完了イベントでデバイストークンを取得して登録。
    window.addEventListener(LOGIN_EVENT_NAME, async (event) => {
        const login_id = event.detail.login_id;
        const device_type = event.detail.device_type;
        await registerDevice(login_id, device_type);
    });
データベースへの登録処理は $.ajax()なり $.post()なりでサーバのAPIを呼び出すだけです。
で、Android アプリは正しく動作するのに、iOS アプリだとエラーの不明な例外で落ちます。
login.is では、イベント発効前に $.ajax で ID が正しいかとかパスワードが正しいかとかやってるのに。
iOS だとデバイストークンの保存APIだけが落ちるんですよね・・・
丸一日追いかけましたよ・・・

ようやく

という書き出しから想像つくと思うけど。
要するにね、カスタムイベントハンドラ内での $.ajax だから落ちるんだと分かった。

login.jsでdevice_token.jsのクラスを依存させて次のように書き換えました。

    if(this.IsMobile) {
        const tokener = new DeviceTokenClass();
        var device_token = await tokener.getDeviceToken();
        if(device_token != null) {
            var result = await tokener.registDeviceToken(login_id, device_type, device_token);
        }
    }

まとめ

せっかく2つのクラスを分離してたけど、それができなくて残念でしたが。
Androidは動くけど、iOS では動かない!
なぜじゃ!?
という事態になったら、こういった部分が引っかかってるかもです。
納期ギリギリまにあったので、よし!w

めでたしめでたし。

0 件のコメント:

コメントを投稿