前提・実現したいこと
swiftでwebサーバ(ローカルサーバ)から値を取ってきたいです。
発生している問題・エラーメッセージ
webサーバには「0」か「1」が書かれているテキストファイルがあるのですが、テキストファイルには0と書いてあるのに取ってきた値は1になっています。正常に値を取得できる場合もあるので、何が起きているのかさっぱり分からなくて困っています。
### 該当のソースコード func get(){ let url = URL(string:http://localhost〜) let config = URLSessionConfiguration.default config.requestCachePolicy = .reloadIgnoringLocalCacheData let session = URLSession(configuration: URLSessionConfiguration.default) let task = session.dataTask(with: url!, completionHandler: { (data, resp, err) in let getData: NSString? = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)! if Int(getData as! String) != nil{ value = Int(getData as! String)! print(value) <-------修正しました。 } }) task.resume() } ```swift ### 試したこと Charlesを用いてパケットキャプチャをしたのですが、正常に値を取得できているときはlocalhostとやりとりしていることが表示されますが、正常に値を取得できていないときは何も表示されません。 正常に値を取得できていないときは何が起きているのかと、その解決策を教えていただきたいです。 よろしくお願いいたします。
valueの初期値にはどのような値が入っていますでしょうか?また、getDataをコンソールに出力した際に正常に値を取得できた時とできなかった場合の値はどうなるか教えていただくことはできますでしょうか?
ご質問ありがとうございます。valueにはInt型で1が代入されています。
あと言い忘れていたのですが、xcodeのシミュレータで実行した時にこの現象が生じることが多く、実機で実行したときはほとんど起きていないような印象です。
getDataに関しては1が取得できたときは「Optional(1)」と表示され、0が取得できたときは「Optional(0)」が表示されています。
URLの中身は "http://localhost〜" ですか? iOS端末のブラウザでそのURLを開いた時に期待するデータは表示されますか?
「テキストファイルには0と書いてあるのに取ってきた値は1になっています。」は値が取得できているときにも起きていますでしょうか?また、「テキストファイルには0と書いてあるのに取ってきた値は1になっています。」はどうやって確認されていますでしょうか?(画面に表示しているのでしょうか?)
kakajikaさん、ご質問ありがとうございます。URLの中身は正確にはlocalhostの後にも続いておりますが、特に必要ないかと思ったので「〜」という風に省略させていただきました。今、確認したところブラウザでこのURLを開いた時に期待するデータは表示されました。
newmtさん。値は毎回取得されるのですが、その値がテキストファイルに書いてある値と同じではないことがあります。ちょっと答えになっていなかったらすみません。確認方法は、サーバから取得した値をコンソールに表示するようにしているので、その値とサーバにあるテキストファイルの値が異なれば「違う」という風に判断しています。また、最初の質問にも「正常に取得できる時もある」と書きましたが現在は正常に取得できる状態になっています。しかしまた作業を進めると正常に取得できない状態が訪れるので、この現象が何なのか知りたいです。
コンソール出力はvalueに値を設定している直後でされていますでしょうか?「テキストファイルには0と書いてあるのに取ってきた値は1になっています。」とのことから値が設定できず、初期値の1が出力されている場合があるのかと思ったのですが。
そういうことですね。ちょっと上のソースコードを色々と消し過ぎてしまったのですが、実際はvalueのすぐ下にprint(value)が入っています。なのでif文の中を通っているので初期値の1ではないような気がします。ややこしくしてすみません。
let getData: ... の上の行に if let data = data {print(String(data: data, encoding: .utf8) ?? "nil string")} else {print("nil data")} を追加して出力を教えて下さい。
fuzzballさん、回答ありがとうございます。質問に書いたのですが、この現象は失敗するときもあれば正常に値を取得できる時もあって現在ではなぜか正常に値を取得できています。なのでfuzzballさんのコードを入力したところ、テキストファイルに書いてある値が正常に表示されました。なので、テキストファイルに1と書いてあれば「Optional(1) 1」と表示されました。
おかしくなったときに出力を教えて下さい。
サーバーとの通信の問題のような気がするので、別のタグも付けた方が良いような。
URLSession(configuration: config) だとどうでしょうか?(なんかキャッシュ効いてそう)
fuzzballさんのおっしゃるようにキャッシュ周りが怪しい気がしますね。上記の方法でできなかった場合、let task = URLSession.shared.dataTaskとして試してみてもよろしいでしょうか?また、Simulatorのキャッシュの削除もされてみた方がよいかもしれません。https://youtachannel.com/ios-simulator-reset-content-and-setting/
fuzzballさん、タグに関してはちょっと投稿が初めてだったので適当にやってしまいました。すみません。またおかしくなったら出力もやってみます。僕もキャッシュ周りなのかと思い、ignoringLocalCacheDataとか入れてみたんですがURLSession(configuration: config)にしないと意味なかったですかね。これもまたおかしくなったら試してみます!
newmtさん、知識が薄いまま使っているので質問があるのですがURLSession.shared.dataTaskの「shared」を入れるとどう変わるのでしょうか?あとSimulatorのキャッシュの削除とソースコードに書いてあるreloadIgnoringLocalCacheDataは異なるものなのでしょうか?
sharedはURLSessionのデフォルトの設定を提供するインスタンスでconfigurationの設定が不要になります。URLSessionは自分でインスタンス化するとメモリーリークを起こすことがあるのでもしかしたらそれが関連しているのかと考え、その心配がないsharedを使ってみるとどうかなと思いました。https://qiita.com/SatoTakeshiX/items/b65f5518a025c23e1d9d reloadIgnoringLocalCacheDataも同じ効果があると思いますが、simulatorはたまにおかしくなることがあるので念のため一度クリアしてみて検証した方がよいかと思い提案してみました。
newmtさん、メモリリークの問題があるんですね。また同じ現象に出会ったら両方とも試してみますね。細かく教えていただきありがとうございます!
回答1件
あなたの回答
tips
プレビュー