iOS Swift - Google Place API (Web) 以一种奇怪的格式返回 JSON

Posted

技术标签:

【中文标题】iOS Swift - Google Place API (Web) 以一种奇怪的格式返回 JSON【英文标题】:iOS Swift - Google Place API (Web) returns JSON in a strange format 【发布时间】:2017-01-09 21:29:02 【问题描述】:

我正在使用 Swift 3 构建一个 ios 应用程序,并且我正在使用 Google Places API 来获取地点数据。我正在使用 iOS API 来获取我需要的大部分数据。但我还需要获取 iOS API 尚未(尚未)提供的开放时间。

所以我必须查询 Web API 以获取该信息。事情的请求方面工作正常,但是,一旦我得到结果并使用JSONSerialisation将其转换为 JSON,然后在控制台中打印输出,这个 JSON 的格式很奇怪,我正在努力解析它.

当我将它粘贴到 JSON 阅读器中时,它说它无效。

这是我觉得奇怪的 JSON,带有这些“(”和“=”:

["html_attributions": <__NSArray0 0x17001ccf0>(

)
, "result": 
    "address_components" =     (
                
            "long_name" = 611;
            "short_name" = 611;
            types =             (
                "street_number"
            );
        ,
                
            "long_name" = "Post Street";
            "short_name" = "Post St";
            types =             (
                route
            );
        ,
                
            "long_name" = "Lower Nob Hill";
            "short_name" = "Lower Nob Hill";
            types =             (
                neighborhood,
                political
            );
        ,
                
            "long_name" = "San Francisco";
            "short_name" = SF;
            types =             (
                locality,
                political
            );
        ,
                
            "long_name" = "San Francisco County";
            "short_name" = "San Francisco County";
            types =             (
                "administrative_area_level_2",
                political
            );
        ,
                
            "long_name" = California;
            "short_name" = CA;
            types =             (
                "administrative_area_level_1",
                political
            );
        ,
                
            "long_name" = "United States";
            "short_name" = US;
            types =             (
                country,
                political
            );
        ,
                
            "long_name" = 94109;
            "short_name" = 94109;
            types =             (
                "postal_code"
            );
        
    );
    "adr_address" = "<span class=\"street-address\">611 Post St</span>, <span class=\"locality\">San Francisco</span>, <span class=\"region\">CA</span> <span class=\"postal-code\">94109</span>, <span class=\"country-name\">USA</span>";
    "formatted_address" = "611 Post St, San Francisco, CA 94109, USA";
    "formatted_phone_number" = "(415) 817-1391";
    geometry =     
        location =         
            lat = "37.7877411";
            lng = "-122.4120067";
        ;
        viewport =         
            northeast =             
                lat = "37.78791149999999";
                lng = "-122.4119977";
            ;
            southwest =             
                lat = "37.7876843";
                lng = "-122.4120337";
            ;
        ;
    ;
    icon = "https://maps.gstatic.com/mapfiles/place_api/icons/cafe-71.png";
    id = 6a6d8b640d5260886eac5ce1b3aa73b3b0d0bb1c;
    "international_phone_number" = "+1 415-817-1391";
    name = "Joy's Place";
    "opening_hours" =     
        "open_now" = 1;
        periods =         (
                        
                close =                 
                    day = 1;
                    time = 0000;
                ;
                open =                 
                    day = 0;
                    time = 0800;
                ;
            ,
                        
                close =                 
                    day = 2;
                    time = 0000;
                ;
                open =                 
                    day = 1;
                    time = 0700;
                ;
            ,
                        
                close =                 
                    day = 3;
                    time = 0000;
                ;
                open =                 
                    day = 2;
                    time = 0700;
                ;
            ,
                        
                close =                 
                    day = 4;
                    time = 0000;
                ;
                open =                 
                    day = 3;
                    time = 0700;
                ;
            ,
                        
                close =                 
                    day = 5;
                    time = 0000;
                ;
                open =                 
                    day = 4;
                    time = 0700;
                ;
            ,
                        
                close =                 
                    day = 6;
                    time = 0000;
                ;
                open =                 
                    day = 5;
                    time = 0700;
                ;
            ,
                        
                close =                 
                    day = 0;
                    time = 0000;
                ;
                open =                 
                    day = 6;
                    time = 0800;
                ;
            
        );
        "weekday_text" =         (
            "Monday: 7:00 am \U2013 12:00 am",
            "Tuesday: 7:00 am \U2013 12:00 am",
            "Wednesday: 7:00 am \U2013 12:00 am",
            "Thursday: 7:00 am \U2013 12:00 am",
            "Friday: 7:00 am \U2013 12:00 am",
            "Saturday: 8:00 am \U2013 12:00 am",
            "Sunday: 8:00 am \U2013 12:00 am"
        );
    ;
    photos =     (
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/109383364523945736298/photos\">Kathleen S</a>"
            );
            "photo_reference" = "CoQBdwAAAFE8a_M5quVcX6frenilHEFVXTycrrhj5R3MoS5sd_vKG1Gj46aJVAvVl_a4HVcPS4G5Z2JS00Pugdegn4is9KSfwIw6IoMNBL1zo3hK2dQjfArUezH9wfSYpNJCNzi4bUO6EesC4bT74B1-hzM6Us4gzKpLLAfImaF3VTeRX-SGEhCLAqUUWZsgueYvTkx8mEi8GhRCDxXbJR-ddaQFwJizvZIKa4EYKA";
            width = 4032;
        ,
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/109935156740971751576/photos\">Jake Lim</a>"
            );
            "photo_reference" = "CoQBdwAAANPkBrIvYxn3UrYliLvLgk3Z4tOmS_twOv9nbMSTFmAR00Mff8XCMWQRUeigOYw1dSheyerBgimteHAHdRMzTCAWkJ7V2yB0eBS5HBewcw2yKmGHrCuCxZDdBlovGzJrwhfo5cAUB0lFDIfAXfDGnNWifD8OmLdfEzsZt97peyIrEhC84xqRQnlK32XjZkXE5huQGhQiPI0EjQ284RkMqiYxwnoHVpXOMg";
            width = 4032;
        ,
                
            height = 2048;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/111937150500795140908/photos\">Hope Lynch</a>"
            );
            "photo_reference" = "CoQBdwAAAFMi1hIXlNKawhA7RPl9Oah4OS6ZZyNnBRpgkHtT5gCC0brwkl55azVyulgOLsYeBkz7lpDgrpW4_9A2vg6Dtcg1bf3vVYVb1PbvADXJAV8yNwmRu9xvfSaPlgl3ty7WKW2tl8Znv8pnTMtOxfYBiTqLuFpLiEdt03pmqQMtrTKSEhADBNOSal9jDonQAMac7ghIGhTkHYMlxquEKYBuKNlbJxYY2sMmxQ";
            width = 1536;
        ,
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/100358998671099081635/photos\">\Uc784\Uc77c\Uc8fc</a>"
            );
            "photo_reference" = "CoQBdwAAAClp7S-w50auLq1Rtet0Glz5UjwWmSFGWKsceURE2ydHve0hFYZqf-OewYNm7xqRBA_Vdtl-nNSIgHawN5JCfyXW48fMRFi7L1mYiycxPjpZSwcH8VlQUisS1dEURkbSaY7lBH1niz197x0hhK0eTIdaPjsXboXcij7xQm6bsYSYEhDt416My2DDwuNUg7MWDrzDGhTIxwfK1eBLCjzto2X_10Ed9pvsyQ";
            width = 4032;
        ,
                
            height = 5312;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/113957702965980710581/photos\">Tim Lee</a>"
            );
            "photo_reference" = "CoQBdwAAANNU12JQOxIa6Y4MBHzNedo42kZmStvSbw_JF-lhdCOtj7QoiuwfWvj1MjECq29AO7CM3QFeJiQQn3cV3GWilWHoI0EDXBodlGRe3MAG6tNhBnKBYB_jNuM_muu2o1ngWmsOXP6cmcuZmxK1z5w5cDX_aUrpli4vkKRkNuqIdbc_EhACCVmjsS6GxgLanF9s9KrVGhSEL_DpaNArYwocJzkX688WFLsEUQ";
            width = 2988;
        ,
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/109383364523945736298/photos\">Kathleen S</a>"
            );
            "photo_reference" = "CoQBdwAAAK8OjkKwRH84A_OKMhCXVemX8vxLS8nCp7c30JOvt7SiqGL5_XQCKz03ZiH-Tq2sshn_UBKttz3oyDJIhfAT2VTuDZgnbAPCSlNQUoP80yeATWPJJFcjJ4XxsKcQHF6Y5IDFzszEIAJYhMBQJ9I6RKMaBGMlRftIZeAEkFhN5AEtEhAozH6UEf-m0XthHPES1ldPGhTB3-JgPzRJ8aDX-B5_SyW2vs4E8Q";
            width = 4032;
        ,
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/114832380918896847951/photos\">Deby Lepage</a>"
            );
            "photo_reference" = "CoQBdwAAAJyut1B1yUQD6mq1FD8gQVNKo16sS6-xbnGeSs8jDtb3C5oF_oUcoUGpLTnQpHqxHfsFh7oL7cBud_h-h0xc2fhNuIkMBFQEWeZhCrmoqph5U79sH98jtOKJgjxs6i0W3-cyDlyURIux8oBfB3QzNhLqeHapJ_WFAMai74Z5ufo1EhDlCT1tkYirOAlgg18i1MVEGhQ_StyBaN3neLaiKNN2s-cTFEPz1w";
            width = 4032;
        ,
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/114832380918896847951/photos\">Deby Lepage</a>"
            );
            "photo_reference" = "CoQBdwAAAJ-OEm5p7FZZFsPIUBBlB-v5uPhGz3K_j9qD4fIF7lUTFUW3I_-O9gy_MZCUkD5XlZJXa2F9kfZ4Ru-Eb989IYc6YQzc3i_N3ozUOyuPhL2FDUqqkl-pltfNJJBoSOlDp4M4Ay9yrKQP6BpUP8i9P9L0gDgv-ycKDIWNh-vUDmtwEhA6F3RmxZ_tsbE131S_RcYoGhTOQTkUt1Zm9b8qUD7yxiWTjemxxQ";
            width = 4032;
        ,
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/109383364523945736298/photos\">Kathleen S</a>"
            );
            "photo_reference" = "CoQBdwAAANkAGV7dv_jVNv_mGmJ9ilcPKJ9Vx24Fs1MEwy0Ce6B6hoGZ-8I0pbFVjS99TicGo3zGdi6eUbpEm76C5XplnnkuM4HGWLN1PkzHk98vVeY4hJRGY1o2qnoLaf6DnvPBmhpbrucCJK9WCNRH3-q1UZ6lzFwgxEwFAxbf-KSwJRqkEhD2Si7TWKZNQcb7bXy29QaVGhR7Yk3dOMasHvsoNwa9y-FMxzNV4w";
            width = 4032;
        ,
                
            height = 3024;
            "html_attributions" =             (
                "<a href=\"https://maps.google.com/maps/contrib/114832380918896847951/photos\">Deby Lepage</a>"
            );
            "photo_reference" = "CoQBdwAAABqKoM9Is_KWHUlzFyDIAOh41GwUaOqPC5EwWqB_uwDTRsB4XbOksl4qylHlSbTuXpRrUUaAETi-I0coY8KyLtS5E6NxcM4f93iMl6kgsb8apJRGziedKV99EUNcdeaTWmWJOuxirP_7wwiadwUiwbmfjZ05e2EkAtfmjCb8vHTYEhDsAfUeyhcyQu_riR-Vrd9JGhRwlTegpWWdYn9uVGVhs02SjIyXsQ";
            width = 4032;
        
    );
    "place_id" = "ChIJheCrEY6AhYARxCkT8_KjDWE";
    rating = "4.4";
    reference = "CmRRAAAAeYm_xV5gsn_eVlrvpkEolaqaHFO0CWS5rWXJ5z5QWX8ReJKLPl6eDnvFM0PD2BNMkgfui9Z42_jmUxCIeTeZi3OEaod73XuU_rzLpRAdlOm8IcTaLX6YeYJeS4qFqZxLEhBUzZmWo-SU9WY4YG8WP8GOGhSwAPbhHWRuZh0X6wC1LMD3Los44A";
    reviews =     (
                
            aspects =             (
                                
                    rating = 2;
                    type = overall;
                
            );
            "author_name" = "Lanxin Chu";
            "author_url" = "https://www.google.com/maps/contrib/117750042826931398790/reviews";
            language = en;
            rating = 4;
            "relative_time_description" = "5 months ago";
            text = "Red bean shaved ice was good and definitely did not skimp out on ingredients! Green tea latte was solid. Ambiance was pretty nice. There were a lot of people studying there; as noted by others this makes for somewhat limited seating sometimes so keep that in mind.";
            time = 1470610849;
        ,
                
            aspects =             (
                                
                    rating = 3;
                    type = overall;
                
            );
            "author_name" = "Esther Gibbs";
            "author_url" = "https://www.google.com/maps/contrib/110692487628239988503/reviews";
            language = en;
            rating = 5;
            "relative_time_description" = "a month ago";
            text = "Delicious food and drink- especially their sweet potato latte! Fairtrade and organic everything and a lovely working environment";
            time = 1479462640;
        ,
                
            aspects =             (
                                
                    rating = 2;
                    type = overall;
                
            );
            "author_name" = "Johnny Wang";
            "author_url" = "https://www.google.com/maps/contrib/103379264202553362035/reviews";
            language = en;
            "profile_photo_url" = "//lh6.googleusercontent.com/-EtpIyKVUteI/AAAAAAAAAAI/AAAAAAAAA4c/riPrz4_6j-s/photo.jpg";
            rating = 4;
            "relative_time_description" = "7 months ago";
            text = "It's been called to my attention that I never reviewed this place, despite the number of times I've visited, which is... surprising. Honestly though, there's not too much to say: I've only ever come here for the patbingsoo, which is massively generous in portion size, and fantastically delicious in flavor, and definitely ideal for sharing. But hey, everything can be a personal serving if you try hard enough.\n\nAs for the place itself, it's a nice, chill little cafe that's been packed every single time I go, so seating can be a little hard to find at times. You'll usually find it occupied by folks busy working away on their laptops.\n\n***Accessibility Info***\n\nVenue - On the smaller side, as far as cafes/coffee shops go, with about 2/3 of the seating being accessible: those along the walls were bench seating, and there's lower coffee table seating towards the right as well, leaving only the middle aisle and outer seats along the sides accessible.\n\nBathroom - Didn't try them.";
            time = 1465162538;
        ,
                
            aspects =             (
                                
                    rating = 2;
                    type = overall;
                
            );
            "author_name" = "Victor Vu";
            "author_url" = "https://www.google.com/maps/contrib/108347888656400683025/reviews";
            language = en;
            "profile_photo_url" = "//lh4.googleusercontent.com/-92ZhOOjfwfE/AAAAAAAAAAI/AAAAAAAAZqA/16j_bEwt6fk/photo.jpg";
            rating = 4;
            "relative_time_description" = "7 months ago";
            text = "Great place to study... when it's quiet. There's enough light to clearly see your paperwork. Music is on the medium side and easy to phase out when you put on headphones, or focus really hard. It's really chill!\n\nFood and drinks are nice. It's a great place for coffee and deserts. Most people get waffles or ice cream here. Their matcha green tea is nice as well.\n\nThe only problem is that there is never enough seating during peak hours and it gets claustrophobic when it's crowded with people doing their homework.\n\nSeats are also cheap and hurt your butt.\n\nThis place usually attracts the Asian crowd.";
            time = 1463551785;
        ,
                
            aspects =             (
                                
                    rating = 1;
                    type = overall;
                
            );
            "author_name" = "Brian Melton";
            "author_url" = "https://www.google.com/maps/contrib/103909645378067844462/reviews";
            language = en;
            "profile_photo_url" = "//lh4.googleusercontent.com/-enGmeXKqYC0/AAAAAAAAAAI/AAAAAAAA4eo/maQQGZ8Etdo/photo.jpg";
            rating = 3;
            "relative_time_description" = "a month ago";
            text = "Expensive, small-sized coffees make this coffee shop feel like poor value-for-money. Limited food options but has great desserts: try the macaroons.";
            time = 1480554027;
        
    );
    scope = GOOGLE;
    types =     (
        cafe,
        restaurant,
        food,
        store,
        "point_of_interest",
        establishment
    );
    url = "https://maps.google.com/?cid=6993426060231780804";
    "utc_offset" = "-480";
    vicinity = "611 Post Street, San Francisco";
    website = "http://www.joysplacecafe.com/";
, "status": OK]

这是我的带有虚拟查询的代码:

let url = URL(string: "https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJheCrEY6AhYARxCkT8_KjDWE&key=[MYAPIKEY]")

let urlRequest = URLRequest(url: url!)


let task = URLSession.shared.dataTask(with: urlRequest) 
    (data, response, error) in

    guard error == nil else 
        print(error!)
        return
    

    guard let responseData = data else 
        print("Error: did not receive data")
        return
    

    do 
        guard let placeData = try JSONSerialization.jsonObject(with: responseData, options: JSONSerialization.ReadingOptions.allowFragments)
            as? [String: Any] else 
                print("error trying to convert data to JSON")
                return
        

        print("The placeData is: \(placeData.description)")

        guard let website = placeData["website"] as? String else 
            print("Could not get the website from JSON")
            return
        
        print("The title is: \(website)")
     catch  
        print("error trying to convert data to JSON")
        return
    

task.resume()

任何帮助了解正在发生的事情将不胜感激。最终目标是获得一个字典,其中键是星期几,值是开放时间。

提前致谢

【问题讨论】:

谢谢埃里克,看来我确实很困惑。会调查的。我是新手;) 【参考方案1】:

问题在于 reponseData 是一个字典,其键 response 包含您想要的实际字典。 JSON 看起来像:


    "result": 
        "website": "example.com"
    

所以正确的代码是:

let url = URL(string: "https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJheCrEY6AhYARxCkT8_KjDWE&key=[MYAPIKEY]")

let urlRequest = URLRequest(url: url!)


let task = URLSession.shared.dataTask(with: urlRequest) 
    (data, response, error) in

    guard error == nil else 
        print(error!)
        return
    

    guard let responseData = data else 
        print("Error: did not receive data")
        return
    

    do 
        guard let placeData = try JSONSerialization.jsonObject(with: responseData, options: JSONSerialization.ReadingOptions.allowFragments)
            as? [String: Any] else 
                print("error trying to convert data to JSON")
                return
        

        print("The placeData is: \(placeData.description)")

        guard let website = (placeData["result"] as? [String : Any])?["website"] as? String else 
            print("Could not get the website from JSON")
            return
        
        print("The title is: \(website)")
     catch  
        print("error trying to convert data to JSON")
        return
    

task.resume()

我只是改变了:

guard let website = placeData["website"] as? String else

到:

guard let website = (placeData["result"] as? [String : Any])?["website"] as? String else

【讨论】:

感谢 Coder256 !有点混乱,因为这是我第一次这样做。我已经用你的代码示例试过了,我得到了我想要的。

以上是关于iOS Swift - Google Place API (Web) 以一种奇怪的格式返回 JSON的主要内容,如果未能解决你的问题,请参考以下文章

适用于 iOS 的 Google Place API

iOS swift将JSON分离成数组

Google place api问题

当我尝试调用 Google Place Markers 时,图像选择器无法正常工作

有没有像 google Place Search API 这样的 Apple API?

Firebase.google.com iOS 中的 Firebase 动态链接(Swift)