質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

[Objective-C]位置情報を取得して座標をサーバに送信するアプリで、サーバ接続に失敗したきにアプリが落ちる

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,266

Satochan24

score 84

Objective-Cで、位置情報を取得して、サーバに座標を送信するアプリを作ったのですが、
サーバ接続失敗時(と思われる)にアプリがしばらくフリーズして落ちてしまいます。
何か対策等ありますでしょうか?あるいは、原因の確認方法(本当にサーバ接続失敗時?あるいはGPS取得失敗時?)
・位置情報取得は、NSTimerクラスで、5秒間隔など、ピッカーを使って変数を渡して自動実行させています。
・落ちないときは、15分くらい落ちない(サーバ接続成功したため?)ときがあることは確認済みです。

スレッド処理をすれば回避できるのではないかと考えています。(あるいはエラー処理か・・・)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

フリーズというのが少し気になりますが、失礼ながらメインスレッドで非同期ではなく同期で通信処理を書いていないでしょうか。
一瞬で終わる処理であれば、同期処理でも良いのですが通信のように一定の時間で完了するものではない可能性がある処理を行うのであれば非同期で実行するなど対策が必要だと思います。

NSTimerを使用して5秒間隔で行っている処理が、以下のようになればクラッシュするような気がします。
・1回目 通信処理を呼び出す
・2回目 1回目の通信が完了していない状態で、もう一度通信処理を呼び出す

仮説が正しければ、5秒間隔ではなく例えば180秒間隔などにすれば発生しないのではないでしょうか。
(逆に0.1秒間隔などにすれば通信完了まで間に合わずに即座に再現するかもしれませんが。)

状況をイマイチ把握出来ていないため、的外れな回答かもしれませんが参考なれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/06/17 18:47

    下記のようなスレッド処理を入れてみたら、改善できました。1回テスト済みですが、あと何回かテストしてみたいと思います。どうもありがとうございました。
    [NSThread detachNewThreadSelector:@selector(reload) toTarget:self withObject:nil];

    キャンセル

  • 2015/06/17 23:24

    こんばんは。
    少しずつ進んでいるようですので、詳細は省きます。

    > サーバからの応答データが届くのが少し遅くなりました。(分単位で)
    > 画面の表示更新が遅れているようです。
    画面の表示更新が遅れているとのことですが、画面の更新はメインスレッドで行われます。
    その画面更新が遅れるということは、メインスレッドが他の処理で占有されていると考えられます。(この場合、良く読んでいませんが通信が怪しいですが・・・)

    またエラー処理を追加してクラッシュしなくなったというのはtry catch を追加したという話ではないですよね?
    そうだとしたら、課題が残っている状態ですので解決して下さいね。

    キャンセル

  • 2015/06/18 11:26

    コメント有難うございました。エラー処理は try catch ではなく、URL接続ができなかったときに処理を中断するもので、その状態だとクラッシュはしなくなりましたが、他のボタンが効きにくいフリーズに近い状態になったので、非同期通信にしたところ、他のボタンも効くようになりました。画面表示が遅れる件は、上記のスレッド処理を入れたら改善されました。(スレッド処理にあまり詳しくなくてすみませんが・・・)

    キャンセル

0

非同期通信なのか同期通信なのかで設計が変わりそうですが・・・。
サーバーレスポンスは正しく処理する方がよいですね。
一応try,catchも入れると安全かもです。
落ちた時のエラーログを見ると原因がわかると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/06/16 09:57

    コメントありがとうございます。そうですね。リトライエラー起こしている可能性高いですね。サーバーから応答データ取得時に送信回数 count++ で数えているのですが、一度にたくさんカウントアップされることも気になっています。
    エラーステップとは何でしょうか?エラーした場合のログを残すような処理でしょうか?

    キャンセル

  • 2015/06/16 10:31

    if( step == CONNECT ){

    - 通信処理 -

    if( RESULT_OK )
    {
    step = RESULT_OK;
    }
    else if( RESULT_NG )
    {
    step = RESULT_NG;
    }
    } else if( step == RESULT_OK ) {
    - 画面遷移等 -
    } else if( step == RESULT_NG ) {
    タップでリトライ
    if( touch ) {
    step = CONNECT;
    }
    }

    大体こんな感じで、通信は1回だけ通るようにします。
    オートリトライの場合は3回までとか、ユーザーに選択させるなど考えられます。

    キャンセル

  • 2015/06/16 14:27

    コメントありがとうございます。
    一応、NSURLConnectionの非同期通信で、成功時と失敗時で下記のように処理しているので、X−code上ではエラー内容が見れると思います。失敗時の回数制限までは入れてませんが、NTTimerを使って、5秒とか10秒とかで周期的にGPSを送信している感じです。

    // TestDelegateクラスで実装したsuccessMethod
    - (void)successMethod:(NSData *)data
    {
    NSLog(@"data: %@", data);
    }

    // TestDelegateクラスで実装したfailedMethod
    - (void)failedMethod:(NSError *)err
    {
    NSLog(@"err: %@", err);
    }

    キャンセル

0

画面にUITextViewを配置して、そこにログを出力するようにしてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/06/15 17:39

    回答、有難うございます。
    そうですね。NSLogでなくても、テキストビューに表示させればログが見れますね。
    やってみます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる