2017-12-27 29 views
1

私はFirebaseに非同期のPOSTリクエストを送信するためにF#の次のスニペットを使用しようとしている:F#の非同期HTTPリクエスト - JSON応答を解析

https://firebase.google.com/docs/reference/rest/auth/#section-sign-in-anonymously

:匿名看板を可能にし、特に以下の操作で 次のように私はそれを呼び出しています
let makePostRequest (url : string) (requestBody : string) = 
    let req = WebRequest.CreateHttp url 
    req.CookieContainer <- new CookieContainer() 
    req.Method <- "POST" 
    req.ProtocolVersion <- HttpVersion.Version10 
    let postBytes = requestBody |> System.Text.Encoding.ASCII.GetBytes 
    req.ContentLength <- postBytes.LongLength 
    req.ContentType <- "application/xml; charset=utf-8" 
    async{ 
     use! reqStream = req.GetRequestStreamAsync() |> Async.AwaitTask 
     do! reqStream.WriteAsync(postBytes, 0, postBytes.Length) |> Async.AwaitIAsyncResult |> Async.Ignore 
     reqStream.Close() 
     use! res = req.AsyncGetResponse() 
     use stream = res.GetResponseStream() 
     use reader = new StreamReader(stream) 
     let! rdata = reader.ReadToEndAsync() |> Async.AwaitTask   
     return rdata 
    } 

let url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=XXXXXXXXXXXXXXXXX" 
    let data = "returnSecureToken=true" 
    makePostRequest url data 

私はF#とビット混乱させるために非常に新しいですこれがどのように機能するかについてd。このリクエストからJSONレスポンスを取得するにはどうすればよいですか?これが完了したときはどうすればわかりますか?これはメインスレッドのUIをブロックしますか?私は何をやっていることはスウィフト次のコードブロック翻訳されています。私たちはメソッドの実行が行われた後に呼び出される完了ブロックを持っているとして、ここでは

Auth.auth().signInAnonymously(completion: { (user, error) in 

     if let err = error { 
      print(err.localizedDescription) 
      return 
     } 

    }) 

をすべては私には理にかなっている、と私たちはuser変数ということを知っていますサーバーから取得した応答が含まれていれば、F#では私にはそれほど意味がありません。

UPDATE:HTTPユーティリティと次のコードスニペットを作成しました::コメント欄で提案後

、私はF#のデータを参照した

let url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=XXXXXXXXXXXX" 
Http.RequestString 
    (url, 
     headers = [ ContentType HttpContentTypes.Json ], 
     body = TextRequest """ {"returnSecureToken": true} """) 

ただし、これはエラーThe value, namespace, type or module Http is not defined

UPDATEを生成します2: 私は次のコードのために解決しました:

let fetchUrl callback url (requestBody : string) =   
    let req = WebRequest.Create(Uri(url)) 
    req.Method <- "POST" 
    let postBytes = requestBody |> System.Text.Encoding.ASCII.GetBytes 
    req.ContentLength <- postBytes.LongLength 
    req.ContentType <- "application/json; charset=utf-8" 
    let reqStream = req.GetRequestStream() 
    reqStream.Write(postBytes, 0, postBytes.Length); 
    reqStream.Close() 

    use resp = req.GetResponse() 
    use stream = resp.GetResponseStream() 
    use reader = new IO.StreamReader(stream) 
    callback reader url 

let myCallback (reader:IO.StreamReader) url = 
    let html = reader.ReadToEnd() 
    let html1000 = html.Substring(0,1000) 
    printfn "Downloaded %s. First 1000 is %s" url html1000 
    html  // return all the html 


let openLandlord() = 
    let url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=XXXXXXXXXXXXXXXXXXX" 
    let requestBody = """ {"returnSecureToken": true} """ 
    fetchUrl myCallback url requestBody 
この式は、型を持つことが期待された

:私は次のエラーを取得する

override x.ViewDidLoad() = 
    base.ViewDidLoad() 
    openLandlord() 

:私はここにopenLandlord関数を呼び出すしかし

https://fsharpforfunandprofit.com/posts/fvsc-download/

:ここでは例として次のよう

uintしかし、ここには文字列があります。

enter image description here

エラー:結合のこの時点で、または前

  1. 不完全な構造の構築物。
  2. コンストラクタ要求の値が定義されていません。
  3. メンバー定義で予期しないキーワードが一致しました。
  4. 値、名前空間、型またはモジュールの応答が定義されていません。
  5. 予期しないメンバー定義で特定されました。
+1

あなたの質問は広すぎます。また、1つの高レベルAPIと別の低レベルAPIを比較します。必要に応じて、要求処理をライブラリに委譲することができます。例えば、FSharp.Dataには素晴らしいHTTPユーティリティがあります:http://fsharp.github.io/FSharp.Data/library/Http.html –

+0

私はそれが広すぎるとは思わない...私がしたいのは、 UIをブロックせずに非同期的にHTTP POST要求を受け取り、次にこの要求のJSON応答をクロージャーブロック(または同等のもの)で取得します。私はHttp.fsを使ってみましたが、これは明らかにxamariniosにはインストールされません – Alk

+1

申し訳ありませんが、あまりにも幅広い答えが必要な詳細を説明するために、応答データからJSONを取得したいだけなら、FSharp.Dataまたは.NET Newtonsoft.JSONのF#固有のJSON型プロバイダを使用できます。両方の例がたくさんあります。非同期操作を使用する場合、UIスレッドは問題ありません。 –

答えて

1

チェック次のコード:

open System 
open System.Net 
open FSharp.Data 

type Response = JsonProvider<""" { "name":"John", "age":94 } """> 

[<EntryPoint>] 
let main argv = 
    let request() = 
    async { 
     let url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=XXXXXXXXXXXX" 
     return! Http.AsyncRequestString 
     (url, 
      headers = [ "Content-Type", HttpContentTypes.Json ], 
      body = TextRequest """ {"returnSecureToken": true} """) 
    } |> Async.Catch 
    let result = request() 
       |> Async.RunSynchronously 
    match result with 
    | Choice1Of2 text -> let json = Response.Parse text 
         printfn "name: %A" json.Name 
    | Choice2Of2 e -> printfn "request failed: %A" e 
    0 // return an integer exit code 

タイプがセットアップで作業していない提供している場合は、これが役立つことがあります。https://github.com/Microsoft/visualfsharp/issues/3303

がサービスから期待されているもので、サンプルJSONを交換してください。

+0

あなたはアップデートを見ていただけますか? – Alk

+0

これは非同期ではなく、JSONを解析せず、エラーをキャッチしません... –

+0

私は知っています、問題はiOS設定で動作するようにコードを取得できないことです。私はF#の初心者で、コード内のコントロールフローとその使い方を実際に理解していないので、ペーストをコピーして理解できないようにしたくないのです...そのコードはるかに簡単で、どのように動作するのか理解しています。 – Alk

関連する問題