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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Q&A

解決済

3回答

2073閲覧

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

Satochan24

総合スコア113

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

0グッド

0クリップ

投稿2015/06/12 09:21

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

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

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

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

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

投稿2015/06/12 09:53

YasuhiroMiyake

総合スコア1336

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Satochan24

2015/06/12 10:14

回答ありがとうございます。NTTimerの通信処理、確かに1回目完了していなくて2回目の処理が起こっている可能性あると思います。もう少し調べてまた後日コメントします。
Satochan24

2015/06/15 08:49

同期通信でした。。。 とりあえず、エラー処理を追加してクラッシュはしなくなりましたが、その間、他のボタン(一時停止など)が効きにくくなったので、非同期通信への変更を検討中です。 現状、こんな感じです。 NSError *err; NSData *contents_2 = [NSURLConnection sendSynchronousRequest:req_2 returningResponse:&res_2 error:&err]; if (err) { NSLog(@"サーバへの接続に失敗しました。"); } else {
Satochan24

2015/06/17 00:58

下記のサイトを参考にして非同期通信にしてみました。 http://grandbig.github.io/blog/2014/09/07/async-and-sync/ クラッシュはなく、他のボタンが効きづらいなどのフリーズもほぼなくなりましたが、 サーバからの応答データが届くのが少し遅くなりました。(分単位で) 非同期にした影響でしょうか?とりあえず、トレースして調査中です。
Satochan24

2015/06/17 07:32

どうも、画面の表示更新が遅れているようです。ボタンも表示される前に押せる状態になっています。何か対応方法ありますでしょうか?別スレッドで画面更新とかでしょうか?
Satochan24

2015/06/17 09:47

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

2015/06/17 14:24

こんばんは。 少しずつ進んでいるようですので、詳細は省きます。 > サーバからの応答データが届くのが少し遅くなりました。(分単位で) > 画面の表示更新が遅れているようです。 画面の表示更新が遅れているとのことですが、画面の更新はメインスレッドで行われます。 その画面更新が遅れるということは、メインスレッドが他の処理で占有されていると考えられます。(この場合、良く読んでいませんが通信が怪しいですが・・・) またエラー処理を追加してクラッシュしなくなったというのはtry catch を追加したという話ではないですよね? そうだとしたら、課題が残っている状態ですので解決して下さいね。
Satochan24

2015/06/18 02:26

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

0

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

投稿2015/06/12 10:58

Stripe

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Satochan24

2015/06/15 08:39

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

0

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

投稿2015/06/12 09:37

MasaakiIrie

総合スコア1021

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Satochan24

2015/06/12 10:18

回答、有難うございます。try,catchも入れてみます。落ちた時のエラーログ、外出してGPS取得しているので、エラーログはXCODEでは見れませんが、何か方法があれば教えてください。ノートPCで車移動とかでしょうか…マックはノートPCが現状ないです。
MasaakiIrie

2015/06/12 14:49

実機に転送すると、xcodeのオーガナイザーでコンソールログがでますよ。
Satochan24

2015/06/15 08:46

コメントありがとうございます。 サーバ接続時にエラー処理を入れたら、とりあえずクラッシュはしなくなりました。 ・・・が、その状態で他のボタンが効きにくく、フリーズに近い状態になるので、非同期通信に変更を検討中です。 こんな感じで。 NSError *err; NSData *contents_2 = [NSURLConnection sendSynchronousRequest:req_2 returningResponse:&res_2 error:&err]; if (err) { NSLog(@"サーバへの接続に失敗しました。"); } else {
MasaakiIrie

2015/06/16 00:31

なんどもリトライエラーを起こしてる可能性はないですか? 失敗した後に、エラーステップへ変更等されてますでしょうか?
Satochan24

2015/06/16 00:57

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

2015/06/16 01: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回までとか、ユーザーに選択させるなど考えられます。
Satochan24

2015/06/16 05: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); }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問