WebAPI를 활용할 때 Optional Binding과 자유형의 Swift 스타일의 코트를 활용한 해설

16734 단어 SwiftiOS
이 문서는 Swift1입니다.0 이전 베타판에 썼던 것.현재의 Swift 사양과 상당히 동떨어진 가능성이 있음

개시하다


오랜만에 찾아온 장마가 맑은 아침에 방심하고 우산도 없이 외출하는 사람이 많을 것이다.매화가 나오기까지 아직 한참 남았는데, 나는 여름이 오기를 바라고 있다.아니면 계속 봄이었으면 좋겠어요.
이번 주에도 원티드리사가 주최한yimajo 행사에 참석해'웹API를 활용할 때 옵티컬 빙딩과 의상을 사용한 스위프트 스타일의 코트를 쓰는 서법 해설'이라는 제목으로 LT를 진행하며 내용을 공개했다.
발표 자료는 제2회 Swift 학습회-TLT회, LT에 설명된 코드는 "WebAPI 사용 시 Optional Binding 및 자유형 Swift 스타일 아우터 쓰기 방법" 슬라이드셰어에 업로드였다.

LT에서 하고 싶은 말.


지난번 첫 학습회와 간담회에서 어떤 사람은 아래의 일을 모른다고 말했다
  • Optional 또는 Optional Binding
  • 클론
  • JSON의 보라색 부분
  • 스위프트를 배우는 기초 위에서 모두가 통과할 수 있는 곳이 아닐까 생각했는데 실제 웹API 코드를 사용하니 이런 곳이 다 잘 보이더라고요. 그리고'어떻게 하면 스위프트처럼 코드를 쓸 수 있을까'이런 얘기가 나오면 난리가 났겠죠.
    따라서 APIClient 제작을 전제로 실제 인코딩은 어떻게 해야 하는지를 설명한다.
    맞아요. GiitHub.
    이 예는 인증이 필요 없는Qita를 사용하여 TableViewController가 인터페이스를 통해 그 데이터를 표시하도록 했다.Qita의 발언이 API에 대한 응답을 얻는 것은 사전의 배열이며 요점은 필요한 매개 변수와 불필요한 매개 변수이다.

    통신 인터페이스의 설계


    QitaAPI 얻기 위한 특정 태그 발언를 호출하는 APIClient 방법은 다음과 같습니다.
    class func items(tagName:String,
                     success:((QiitaItemEntity[]) -> Void)!,
                     failure:((NSError?) -> Void)!) 
    
    첫 번째 파라미터는 특정 탭의string에서 필요하고, 두 번째 파라미터는 통신과 JSON의 해석이 성공했을 때 크론에서QitaItemEnity[]를 되돌려주고, 세 번째 파라미터는 실패했을 때 NSError를 되돌려줍니다.클론은 변수처럼?Optionial에서 nil에 전달할 수 있습니다.
    그나저나 니엘을 벽장에 맡긴 쪽이 니엘 검사를 하면서 벽장을 집행하고 싶다면 아래 줄에 써도 스와프의 장점이다.
    //failureがnilなら実行しないのでクラッシュしない
    failure?(NSError())
    

    통신 인터페이스의 실현


    다음과 같이 실현되다
    //クラス変数(定数)は使えないのでプロパティのgetterでAPIのBASE URLを返す
    //getterなのにgetが省略できているのは何故かちょっと良くわからないのですがそういうものなんでしょう
    class var baseUrlString: String { return "https://qiita.com/api/v1" }
    
    //URLを組み立ててNSURLを返すだけ。APIのエンドポイントとして使う
    class func itemsURL(tagName:String) -> NSURL {
        //tagNameは必須なのでここではnilチェックなどをする責任を持たない
        return NSURL(string: "\(self.baseUrlString)/tags/\(tagName)/items")
    }
    
    //Qiitaの特定タグの記事一覧を取得するAPIをコールし、
    //成功した場合のクロージャか失敗した場合のクロージャで値を取得できるようにする
    class func items(tagName:String,
                     success:((QiitaItemEntity[]) -> Void)!,
                     failure:((NSError?) -> Void)!) {
    
        let url = itemsURL(tagName)
        let request = NSURLRequest(URL: url)
    
        NSURLConnection.sendAsynchronousRequest(request,
            queue: NSOperationQueue.mainQueue(),
            completionHandler:{(response: NSURLResponse!,
                         data: NSData!,
                        error: NSError!) in
                //入力値のエラーチェックは先に行っておき失敗クロージャに返す
                if error != nil {
                    failure?(error)
                    return
                }
                //NSJSONSerializationにnil渡すと例外になるためチェックをしている
                //TODO: オリジナルのNSErrorを作ればいいかもしれないがとりあえずnilを返しておく
                if data == nil {
                    failure?(nil)
                    return
                }
    
                var jsonError: NSError?
                //キャストしつつOptional BindingするのがSwiftっぽい気がする
                if let anyObjects = NSJSONSerialization.JSONObjectWithData(data,
                        options:NSJSONReadingOptions.AllowFragments,
                        error:&jsonError) as? NSDictionary[] {
    
                    //このブロックではJSONが想定通りの配列と辞書になっていることが確定する
    
                    var items = QiitaItemEntity[]()
                    //anyObjectsの全ての要素がNSDictionaryだからfor inできる
                    for dictionary : NSDictionary in anyObjects {
                        if let title = dictionary["title"] as? String {
                            if let urlString = dictionary["url"] as? String {
    
                                let qiita = QiitaItemEntity(title: title, urlString: urlString)
                                qiita.gistUrlString = dictionary["gist_url"] as? String
                                //配列の+=はapendされるっぽい
                                items += qiita
                            }
                        }
                    }
    
                    success?(items)
    
                } else if jsonError != nil {
                    //想定外1(APIサーバーが仕様通りのJSONを返していないなど疑う)
                    failure?(jsonError)
                } else {
                    //想定外2(APIサーバーがメンテナンスモードでJSONを返せていないなどを疑う)
                    //TODO: これもオリジナルのNSErrorを作ればいいかもしれないがとりあえずnilを返しておく
                    failure?(nil)
                }
            }
        )
    }
    
    
    제일 스위프트 같은 부분은 JSON을 JSONObject로 되돌려주는 방법이에요.
    if let anyObjects = NSJSONSerialization.JSONObjectWithData(data,
                                 options:NSJSONReadingOptions.AllowFragments,
                                   error:&jsonError) as? NSDictionary[] {
    
        //このブロックに突入できるのはanyObjectsがnilでない場合
    
    } else if jsonError != nil{
        //異常系の処理1
    } else {
        //異常系の処理2
    }
    
    설명해 주세요, as?JSON의 해석에 따르면 JSONObject의 구조가 NSDictionary의 배열이면 비nil의 부분을 되돌려주고, NSDictionary의 배열이 아니면 nil의 분배 역할을 되돌려준다.
    만약 nil이 아니라면 변수를 속박 변수anyObjects에 대입하는 동시에 이 블록(blocks가 아님)에 들어갈 수 있어 먼저 정상적인 시스템 처리를 인코딩한 다음에 이상 시스템 처리를 추가하는 스타일이 된다.스위프트 스타일로 코딩하면 가독성이 높아질 것 같아요.
    원래API 얻기 위한 특정 태그 발언 Objective-C에서 되돌아오는 값은 id였지만 Objective-C에 적힌 코드 중 대부분은 NSAray와 NSDcitionary에 분배되어 사용되었고 Swift에서도 어느새 NSAray로 사용되었다. NSAray는 NSDictionary[]가 자연스럽게 역할을 분배할 수 없다고 느꼈다.
    이해하기 어려울 수 있으니 조금만 더 설명해 드리자면 NSDictionary[]는 사실상 Arrey이기 때문에 컴파일러의 경고 없이 정상적으로 출연할 수 있습니다.아래와 같이 임시 변수의 코드를 코드로 바꾸면 이해하기 쉬울 것이다.
    //変数を一時的に移しておく(Swiftのメリットが薄くなる)
    let anyObjects[] = NSJSONSerialization.JSONObjectWithData(data,
                                 options:NSJSONReadingOptions.AllowFragments,
                                   error:&jsonError) as? AnyObject[]
    
    if let downCastArray = anyObjects as? NSDictionary[] {
        //このブロックに突入できるのはdownCastArrayがnilでない(NSDictionary[]の)とき
        //anyObjectsが使えるのもこのスコープだけ
    
    } else if jsonError != nil {
        //異常系の処理1
    } else {
        //異常系の処理2
    }
    
    이 코드는 이해하기 쉽지만 letany Object[]는 이미 사용하지 않기 때문에 앞에 있는 코드처럼 역할을 할당하면서 사용하는 변수를 Optional Binding으로 제한하면 스와프 스타일의 코드라고 할 수 있죠.

    총결산Swift 같은 코드를 쓰기 위해서.

  • 속성의 Getter로 클래스 상수 되돌리기
  • 필요없는것도모자간에?
  • NSAray
  • 는 가급적 사용하지 마십시오.
  • 유형이 예상을 초과할 수 있을 때, as?Optional Binding
  • 지금까지 Swift에 대한 이해였습니다.

    기타


    Apple Foundation Framework에서 메소드의 매개변수를 확인합니다!덧일


    애플이 공개한 사전 발표 문서를 보고 애플은 스위프트에서 Foundition Framework를 사용할 수 있도록 전방 파일을 매개 변수로 삼았다!그러나 제 개인적인 임의적인 고찰에서 이것들은 모두 Apple가 어떤 규칙하에서 자동으로 생성한 것입니다. 규격상 엄격하게 검사하고 안전을 확인한 후에 여과합니다!끼고 있는 게 아닌 것 같아서요.
    예를 들어 이번 화제에 등장한 NSJSONserialization.방법 데이터는 일종의 예언이다!매개변수에 nil을 추가하면 ObJC 시대와 마찬가지로 예외가 발생합니다.
    매개 변수에nil을 추가하지 않으려면!끝말?이 두 개 다 안 넣었으면 좋겠는데 없어요.전혀 이해가 안 가요. 발표 우선, 기계적인 거예요!'호'자를 넣어서 그런지 짐작이 간다.
    그래서, 지금 상황에서!의 정확한 사용 방법은 Foundation Framework에 있는 방법의 매개 변수에서 이해되는데 사실은 Optionial의 사용 이해를 방해한다.

    최후


    Swift2.기대하다

    좋은 웹페이지 즐겨찾기