2017-12-27 10 views
1

내가 중포 기지에 비동기 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#과 약간의 혼동에 아주 새로운 해요 이것이 어떻게 작동하는지에 관해서. 이 요청에서 JSON 응답을 얻으려면 어떻게해야합니까? 이것이 언제 완료되는지 어떻게 알 수 있습니까? 그러면 기본 스레드의 UI가 차단됩니까? 내가 뭐하는 거지 것은 스위프트 코드의 다음 블록 번역입니다 : 여기

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

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

    }) 

우리가 방법을 실행 완료 후 호출되는 완료 블록을 가지고 모든 것이 나에게 의미가, 그리고 우리가 알고있는 그 user 변수 의지 서버로부터 얻은 응답을 포함하고 있기 때문에 F #에서 나에게별로 의미가 없습니다.

UPDATE : 주석의 제안에 따라

, 내가 언급 한 F 번호 데이터 : HTTP 유틸리티 다음과 같은 코드 생성 :

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하지만 여기에는 string 유형이 있습니다.

enter image description here

오류 :이나 결합이 시점 전에

  1. 불완전한 구조 구조체.
  2. 생성자 요청의 값이 정의되지 않았습니다.
  3. 회원 정의에서 예상과 일치하지 않는 키워드입니다.
  4. 값, 네임 스페이스, 유형 또는 모듈 응답이 정의되지 않았습니다.
  5. 회원 정의에서 예기치 않은 신분이 확인되었습니다.
+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을 구문 분석하지 않습니다. 오류를 catch하지 않습니다 ... –

+0

문제는 내가 iOS 설정에서 작동하도록 코드를 가져올 수 없다는 것입니다. F #을 처음 접했을 때 코드에서 제어 흐름을 이해하고 사용하는 방법을 이해하지 못한다면 단순히 이해할 수없는 항목을 복사하는 것이 아니라 ... 코드 훨씬 더 간단하고 어떻게 작동하는지 이해합니다. – Alk

관련 문제