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

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

新規登録して質問してみよう
ただいま回答率
87.20%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

解決済

SwiftでWebSocketイベント発火によるAPIコールについて

kazzzstudio
kazzzstudio

総合スコア94

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

2回答

0評価

1クリップ

3343閲覧

投稿2018/05/05 13:07

編集2018/05/05 13:09

現在、チャットクライアントをSwiftで作っています。チャット相手のクライアントはJavascriptで実装済みです。

サーバー側は、Python(Django)で作っていて、クライアントからAPI経由で各種のリクエストを処理しています。
Swift側はAlamofireとSwiftyJSONでAPIを叩いています。

これまでは、すべてのAPIリクエストが正常に処理されていたのですが、チャット実装にともなって、相手から
チャットが更新されたイベントを受け取ったときに、更新されたチャット内容をロードするためにAPIを叩こうと
すると、処理が永久ループにハマってしまい、抜け出すことができずにいます。

こちらがチャットをロードするコードになります。

Swift

func reloadChatData() { let jsonData = loadChat(_registration_id: RData.getRegistrationId()) if(jsonData["status"].string! == "success") { for chat in jsonData["chat"].arrayValue { if (chat["chat_from"] == "D") { let chat = ChatEntity(text: chat["chat"].string!, time: "", userType: .You) chats.append(chat) } else { let chat = ChatEntity(text: chat["chat"].string!, time: "", userType: .I) chats.append(chat) } } } tableView.reloadData() } func loadChat(_registration_id: String) -> JSON { let _commonURL = CommmonURL() var _load_chat_url = _commonURL.SERVER_HOSTNAME + _commonURL.LOAD_CHAT_ENTRY_POINT _load_chat_url = addParameter(url: _load_chat_url, named: "registration_id", value: _registration_id) let response = runQuery(_load_chat_url) let data: Data? = String(describing: response.rawValue).data(using: .utf8) let responseJson = JSON(data!) as JSON return responseJson } private func runQuery(_ _url: String) -> JSON { var responseData: JSON = JSON.null let urlString = _url var keepAlive = true Alamofire.request(urlString, method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON(completionHandler: { response in responseData = JSON(response.result.value!) keepAlive = false print("**") // ********** When I call runQuery from websocket event listener function, the code don't reach this line. ********** }) print(keepAlive) let runLoop = RunLoop.current while keepAlive && runLoop.run(mode: RunLoopMode.defaultRunLoopMode, before: Date(timeIntervalSinceNow: 0.1)) { } return responseData }

上記のreloadChatData()をViewControllerの任意の場所(WebSocketのイベント待受以外の場所)から実行すると、正常にチャットデータが返ってきます。
しかし、下記のコードからreloadChatData()を呼び出すと、runQuery()のkeepAliveがFalseにならずに永久ループにハマってしまいます。
サーバーのログでは、正常にクライアントにレスポンスを返しています。

Swift

override func viewDidLoad() { manager = SocketManager(socketURL: URL(string: SocketURL)!, config: [.log(true), .compress]) socketIOClient = manager.defaultSocket socketIOClient.on(clientEvent: .connect) {data, ack in print(data) // Connect Event is fired... let data : Dictionary<String, String> = ["value": RData.getRegistrationId()] self.socketIOClient.emit("join_room", data) print("socket connected") } socketIOClient.on(clientEvent: .error) { (data, eck) in print(data) print("socket error") } socketIOClient.on(clientEvent: .disconnect) { (data, eck) in print(data) print("socket disconnect") } socketIOClient.on(clientEvent: SocketClientEvent.reconnect) { (data, eck) in print(data) print("socket reconnect") } socketIOClient.on("server_to_client") { data, emitter in print("Get Message from Another Client...") // ********** FAILED ********** self.reloadChatData() } socketIOClient.connect() }

相手(Javascriptクライアント)からチャットを送ると、Xcodeのコンソールには、
print("Get Message from Another Client...")
が出力されます。

WebSocketでデータを受信したときだけの問題なので、なんらかreloadChatData()関数を呼び出す方法に問題があると思うのですが、解決の糸口がつかめません。

どのように実装すればよいのかアドバイスをいただけないでしょうか?
よろしくお願いします。

良い質問の評価を上げる

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

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

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

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

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

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

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

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

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

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。