

楽天レシピAPI取得後、  
「try JSONSerialization.jsonObject」でJSONに変換しようとしたのですが、  
print文で中身を確認したところ、下記のように表示され、変換されませんでした。  
キャスト部分に問題があるのでしょうか。API自体に問題があるのでしょうか。  
ご教示いただけますと幸いです。よろしくお願いいたします。

[code]

    ["result": {
        large =     (
                    {
                categoryId = 30;
                categoryName = "\U4eba\U6c17\U30e1\U30cb\U30e5\U30fc";
                categoryUrl = "https://recipe.rakuten.co.jp/category/30/";
            },
                    {
                categoryId = 31;
                categoryName = "\U5b9a\U756a\U306e\U8089\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/31/";
            },
                    {
                categoryId = 32;
                categoryName = "\U5b9a\U756a\U306e\U9b5a\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/32/";
            },
                    {
                categoryId = 33;
                categoryName = "\U5375\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/33/";
            },
                    {
                categoryId = 14;
                categoryName = "\U3054\U98ef\U3082\U306e";
                categoryUrl = "https://recipe.rakuten.co.jp/category/14/";
            },
                    {
                categoryId = 15;
                categoryName = "\U30d1\U30b9\U30bf";
                categoryUrl = "https://recipe.rakuten.co.jp/category/15/";
            },
                    {
                categoryId = 16;
                categoryName = "\U9eba\U30fb\U7c89\U7269\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/16/";
            },
                    {
                categoryId = 17;
                categoryName = "\U6c41\U7269\U30fb\U30b9\U30fc\U30d7";
                categoryUrl = "https://recipe.rakuten.co.jp/category/17/";
            },
                    {
                categoryId = 23;
                categoryName = "\U934b\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/23/";
            },
                    {
                categoryId = 18;
                categoryName = "\U30b5\U30e9\U30c0";
                categoryUrl = "https://recipe.rakuten.co.jp/category/18/";
            },
                    {
                categoryId = 22;
                categoryName = "\U30d1\U30f3";
                categoryUrl = "https://recipe.rakuten.co.jp/category/22/";
            },
                    {
                categoryId = 21;
                categoryName = "\U304a\U83d3\U5b50";
                categoryUrl = "https://recipe.rakuten.co.jp/category/21/";
            },
                    {
                categoryId = 10;
                categoryName = "\U8089";
                categoryUrl = "https://recipe.rakuten.co.jp/category/10/";
            },
                    {
                categoryId = 11;
                categoryName = "\U9b5a";
                categoryUrl = "https://recipe.rakuten.co.jp/category/11/";
            },
                    {
                categoryId = 12;
                categoryName = "\U91ce\U83dc";
                categoryUrl = "https://recipe.rakuten.co.jp/category/12/";
            },
                    {
                categoryId = 34;
                categoryName = "\U679c\U7269";
                categoryUrl = "https://recipe.rakuten.co.jp/category/34/";
            },
                    {
                categoryId = 19;
                categoryName = "\U30bd\U30fc\U30b9\U30fb\U8abf\U5473\U6599\U30fb\U30c9\U30ec\U30c3\U30b7\U30f3\U30b0";
                categoryUrl = "https://recipe.rakuten.co.jp/category/19/";
            },
                    {
                categoryId = 27;
                categoryName = "\U98f2\U307f\U3082\U306e";
                categoryUrl = "https://recipe.rakuten.co.jp/category/27/";
            },
                    {
                categoryId = 35;
                categoryName = "\U5927\U8c46\U30fb\U8c46\U8150";
                categoryUrl = "https://recipe.rakuten.co.jp/category/35/";
            },
                    {
                categoryId = 13;
                categoryName = "\U305d\U306e\U4ed6\U306e\U98df\U6750";
                categoryUrl = "https://recipe.rakuten.co.jp/category/13/";
            },
                    {
                categoryId = 20;
                categoryName = "\U304a\U5f01\U5f53";
                categoryUrl = "https://recipe.rakuten.co.jp/category/20/";
            },
                    {
                categoryId = 36;
                categoryName = "\U7c21\U5358\U6599\U7406\U30fb\U6642\U77ed";
                categoryUrl = "https://recipe.rakuten.co.jp/category/36/";
            },
                    {
                categoryId = 37;
                categoryName = "\U7bc0\U7d04\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/37/";
            },
                    {
                categoryId = 38;
                categoryName = "\U4eca\U65e5\U306e\U732e\U7acb";
                categoryUrl = "https://recipe.rakuten.co.jp/category/38/";
            },
                    {
                categoryId = 39;
                categoryName = "\U5065\U5eb7\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/39/";
            },
                    {
                categoryId = 40;
                categoryName = "\U8abf\U7406\U5668\U5177";
                categoryUrl = "https://recipe.rakuten.co.jp/category/40/";
            },
                    {
                categoryId = 26;
                categoryName = "\U305d\U306e\U4ed6\U306e\U76ee\U7684\U30fb\U30b7\U30fc\U30f3";
                categoryUrl = "https://recipe.rakuten.co.jp/category/26/";
            },
                    {
                categoryId = 41;
                categoryName = "\U4e2d\U83ef\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/41/";
            },
                    {
                categoryId = 42;
                categoryName = "\U97d3\U56fd\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/42/";
            },
                    {
                categoryId = 43;
                categoryName = "\U30a4\U30bf\U30ea\U30a2\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/43/";
            },
                    {
                categoryId = 44;
                categoryName = "\U30d5\U30e9\U30f3\U30b9\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/44/";
            },
                    {
                categoryId = 25;
                categoryName = "\U897f\U6d0b\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/25/";
            },
                    {
                categoryId = 46;
                categoryName = "\U30a8\U30b9\U30cb\U30c3\U30af\U6599\U7406\U30fb\U4e2d\U5357\U7c73";
                categoryUrl = "https://recipe.rakuten.co.jp/category/46/";
            },
                    {
                categoryId = 47;
                categoryName = "\U6c96\U7e04\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/47/";
            },
                    {
                categoryId = 48;
                categoryName = "\U65e5\U672c\U5404\U5730\U306e\U90f7\U571f\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/48/";
            },
                    {
                categoryId = 24;
                categoryName = "\U884c\U4e8b\U30fb\U30a4\U30d9\U30f3\U30c8";
                categoryUrl = "https://recipe.rakuten.co.jp/category/24/";
            },
                    {
                categoryId = 49;
                categoryName = "\U304a\U305b\U3061\U6599\U7406";
                categoryUrl = "https://recipe.rakuten.co.jp/category/49/";
            },
                    {
                categoryId = 50;
                categoryName = "\U30af\U30ea\U30b9\U30de\U30b9";
                categoryUrl = "https://recipe.rakuten.co.jp/category/50/";
            },
                    {
                categoryId = 51;
                categoryName = "\U3072\U306a\U796d\U308a";
                categoryUrl = "https://recipe.rakuten.co.jp/category/51/";
            },
                    {
                categoryId = 52;
                categoryName = "\U6625\Uff083\U6708\Uff5e5\U6708\Uff09";
                categoryUrl = "https://recipe.rakuten.co.jp/category/52/";
            },
                    {
                categoryId = 53;
                categoryName = "\U590f\Uff086\U6708\Uff5e8\U6708\Uff09";
                categoryUrl = "https://recipe.rakuten.co.jp/category/53/";
            },
                    {
                categoryId = 54;
                categoryName = "\U79cb\Uff089\U6708\Uff5e11\U6708\Uff09";
                categoryUrl = "https://recipe.rakuten.co.jp/category/54/";
            },
                    {
                categoryId = 55;
                categoryName = "\U51ac\Uff0812\U6708\Uff5e2\U6708\Uff09";
                categoryUrl = "https://recipe.rakuten.co.jp/category/55/";
            }
        );
        medium =     (
        );
        small =     (
        );
    }]
    
[/code]

[code]

     //リクエスト
     let task : URLSessionTask = URLSession.shared.dataTask(with: url, completionHandler: {data, response, error in
                            
      do {
         let recipeData = try JSONSerialization.jsonObject(with: data!, 　　　options:JSONSerialization.ReadingOptions.allowFragments) as! [String : Any]
    
      print(recipeData)
                                   
     }
     catch{
    
      print(error)
     }
      })        
    
[/code]


CC BY-SA 4.0
2020-06-22T08:50:57.453
67900
2020-06-22T10:33:15.080
2020-06-22T10:33:15.080
3060
40671
question
swift json api
楽天レシピAPI取得後、JSONに変換したい


JSON形式のAPIについて少し勘違いをしておられるようです。

まず、  
_**「楽天レシピAPI」は元々結果をJSON形式で返しています。それを「JSONに変換」する必要はありません**_

APIの返したJSON text形式のデータを見たければ、`try JSONSerialization.jsonObject`の **前**
に次の一行を入れてみて下さい。

[code]

            print(String(data: data!, encoding: .utf8)!)
    
[/code]

* * *

また、  
_**`JSONSerialization.jsonObject`はJSON形式のデータからiOS/Objective-C/(Swift)で扱えるデータ型に変換するもの**_
です。

「JSONに変換」するためのメソッドではありません。

変換後の結果は以下のようなデータ型になります。

[code]

    JSON object → NSDictionary
    JSON array  → NSArray
    JSON string → NSString
    JSON number → NSNumber
    true/false  → NSNumber
    
[/code]

あなたのコードでは、変換後に一番外側の`NSDictionary`をSwiftの`Dictionary<String,
Any>`型にさらに変換しているので、「Swiftの`Dictionary`形式」「`NSDictionary`形式」「`NSArray`形式」などが入り混じった形式で`print(recipeData)`の結果が表示されています。

`print(error)`ではなく`print(recipeData)`が実行されていると言うことは、

_**元のデータは正しいJSON形式であり、`JSONSerialization.jsonObject`での変換は成功した**_

と言うことになります。

* * *

`print(recipeData)`の結果がJSON形式になっていないのは当たり前なので、そんなことは気にせずに **取得したデータをどう使うか**
、を気にして下さい。

例えば、以下のようなコードを実行すると、

[code]

        do {
            
            if
                let jsonData = data,
                let recipeData = try JSONSerialization.jsonObject(with: jsonData) as? [String : Any],
                let result = recipeData["result"] as? [String: Any],
                let large = result["large"] as? [[String: Any]]
            {
                for category in large {
                    print(category["categoryName"] as? String ?? "")
                    print(category["categoryUrl"] as? String ?? "")
                }
            } else {
                print("Bad data", data)
            }
        } catch{
            print(error)
        }
    
[/code]

(このAPIの場合、`JSONSerialization.ReadingOptions.allowFragments`は意味を持たないと思われるので、`options:`の指定は省略してあります。)

こんな出力が得られます。

[code]

    人気メニュー
    https://recipe.rakuten.co.jp/category/30/
    定番の肉料理
    https://recipe.rakuten.co.jp/category/31/
    定番の魚料理
    https://recipe.rakuten.co.jp/category/32/
    卵料理
    https://recipe.rakuten.co.jp/category/33/
    ご飯もの
    https://recipe.rakuten.co.jp/category/14/
    パスタ
    https://recipe.rakuten.co.jp/category/15/
    麺・粉物料理
    https://recipe.rakuten.co.jp/category/16/
    汁物・スープ
    https://recipe.rakuten.co.jp/category/17/
    ...(以下略)
    
[/code]

* * *

何か疑問点などありましたら、この回答へコメントしてお知らせください。


CC BY-SA 4.0
2020-06-22T10:30:25.680
67902
2020-06-22T10:30:25.680
13972
67900
answer