shihominorth
@shihominorth

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

QiitaAPIで投稿した記事のタイトルを変更できない

前提・実現したいこと

QiitaAPIを使って投稿した記事のタイトルを変更するためにpatchをしたところ、エラーが出てきて変更ができない

発生している問題・エラーメッセージ

Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "id", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").", underlyingError: nil)))

該当のソースコード

 func edit(article: Article, newTitle: String, completion: @escaping (Result<Article, Error>) -> Void) {
        
        let endPoint = "items/\(article.id)"
        guard let url = URL(string: host + endPoint) else { return }
        
        let headers: HTTPHeaders = [
            "Content-Type": "application/json",
            "Authorization": "Bearer \(UserDefaults.standard.accessToken)"
        ]
        
        let parameters: Parameters = [
            "title": newTitle,
            "body": article.body
        ]
        
        
        AF.request(url, method: .patch, parameters: parameters, headers: headers).responseDecodable { (response: AFDataResponse<Article>) in
            
            do {
                guard
                    let data = response.data else {
                        completion(.failure(APIError.invaliedData))
                        return
                    }
                
                if let err = response.error {
                    completion(.failure(err))
                }
                
                let json = try? JSON(data: data)
                guard
                    let jsonData = json,
                    let article = Article(json: jsonData)
                else {
                    return
                }
                
               
                completion(.success(article))
                    
                
            }
            
            
        }
        

試したこと

  • CodingKeyのenumが必要と調べたら出てきたので、実装しました。
struct Article {
    
    let id: String
    let url: String
    let title: String
    let lgtm: Int
    let body: String

    enum CodingKeys: String, CodingKey {
        case id, url, title, body, lgtm = "likes_count"

    }

    init(id: String, url: String, title: String, lgtm: Int, body: String) {
       
        self.id = id
        self.url = url
        self.title = title
        self.lgtm = lgtm
        self.body = body
    
    }
    
    init?(json: JSON) {
    
        guard
            let id = json["id"].string,
            let url = json["url"].string,
            let title = json["title"].string,
            let lgtm = json["likes_count"].int,
            let body = json["body"].string
        else {
            return nil
        }
        
        self.id = id
        self.url = url
        self.title = title
        self.lgtm = lgtm
        self.body = body
    
    }
    
   
    
    
}

extension Article: Codable {

    init(from decoder: Decoder) throws {
   
       let values = try decoder.container(keyedBy: CodingKeys.self)

        id = try values.decode(String.self, forKey: .id)
        url = try values.decode(String.self, forKey: .url)
        title = try values.decode(String.self, forKey: .title)
        lgtm = try values.decode(Int.self, forKey: .lgtm)
        body = try values.decode(String.self, forKey: .body)
        
   
   }
}

  • curlで同じことをしようとしたのですが、下記のエラーが出て何も対処できませんでした。後ほどそちらも質問を投稿します。
{"message"{"message":"Unauthorized","type":"unauthorized"}:

補足情報(FW/ツールのバージョンなど)

参考url

https://qiita.com/kai_kou/items/663d3f7bbc4da4ccf62d
https://qiita.com/kai_kou/items/663d3f7bbc4da4ccf62d

0

1Answer

ちょうどやりたいことがあったので Qiita API を使ってみた際に躓きそうなことがあったので、コメントまで。

  • Patch だと Body/Title が Required
  • アクセストークンで Write がついてるか?

流石にこんなところは見落としてないとは思いますが・・

0Like

Your answer might help someone💌