在Swift

时间:2019-12-08 21:35:52

标签: ios swiftui photo google-places google-photos-api

我正在尝试使用Google的Places API提供的“ photo_reference”显示特定位置的照片。

当前,我正在使用Google Places API的“ Place Details”请求来获取有关特定位置的信息,但无法显示这些位置的照片。 Google在“位置详细信息”响应中提供了“照片参考”,该照片应用于获取特定图像,但是文档here对于显示操作方式不是很有帮助。

我目前正在这样发出Google Place Details请求: (我有一个创建网址的功能,然后是一个发出请求的功能)

    func googlePlacesDetailsURL(forKey apiKey: String, place_ID: String) -> URL {
        print("passed  place_ID  before url creation ", place_ID)

        let baseURL = "https://maps.googleapis.com/maps/api/place/details/json?"
        let place_idString = "place_id=" + place_ID
        let fields = "fields=geometry,name,rating,price_level,types,opening_hours,formatted_address,formatted_phone_number,website,photos"
        let key = "key=" + apiKey

        print("Details request URL:", URL(string: baseURL + place_idString + "&" + fields + "&" + key)!)
        return URL(string: baseURL + place_idString + "&" + fields + "&" + key)!
    }


    func getGooglePlacesDetailsData(place_id: String, using completionHandler: @escaping (GooglePlacesDetailsResponse) -> ())  {

        let url = googlePlacesDetailsURL(forKey: googlePlacesKey, place_ID: place_id)

        let task = session.dataTask(with: url) { (responseData, _, error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }

            guard let data = responseData, let detailsResponse = try? JSONDecoder().decode(GooglePlacesDetailsResponse.self, from: data) else {
                print("Could not decode JSON response. responseData was: ", responseData)
                return
            }
            print("GPD response - detailsResponse.result: ", detailsResponse.result)

                completionHandler(detailsResponse)

        }
        task.resume()

    }

有人知道如何在Swift中使用“ photo_reference”发出Google Place Photo请求,并显示返回的照片吗?

2 个答案:

答案 0 :(得分:1)

据我了解,您似乎必须使用Photo_reference创建一个新的URL,该URL是从位置搜索或位置详细信息请求返回的。

您认为photo_reference不是图像,而是一个Http引用,您可以使用它来访问图像,使用该引用,您将必须替换下面的字符串并访问该链接以返回图像

https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=YOUR_API_KEY

“ Your_Api_Key”显然是它的意思,您必须访问返回的照片参考并使用replaceCharactersInRange并替换以下链接中的“照片参考”。

maxwidth可以由您决定,具体取决于您需要的图像大小。

答案 1 :(得分:1)

我知道我要回答这个问题很晚了,很抱歉,我一直很忙,但是我设法为您完成了这件事,这只是我的看法,我仍然对IOS还是陌生的设计可能并不完美,我向您保证它会起作用。要记住的一件事是,并非每个地方都有photo_reference,因此,如果图像被设置为nil值或在创建URl时,您将不得不进行错误处理。会引发异常,请看下面的代码,我将其全部放在一个方法中,但是如果您可以将其分解为几个方法来设置图像和获取数据,那将是一个好习惯。我也很喜欢研究这个问题,请多多反馈。谢谢您,祝您好运。

PS:这是在目标C中,因此您需要做一些工作以对不起我不够快而无法在其中生成它的情况

-(void)fetchedData:(NSData *)responseData {
    //parse out the json data
    NSError* error;
    NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:responseData

                          options:kNilOptions
                          error:&error];

    //Hardcoded placeId for testing purposes
    NSString *placeId = @"ChIJoS8a5GWM4kcRKOs9fcRijdk";

    //Filtered the json to access all the location Ids/place Ids
    NSArray *locations = [json valueForKeyPath:@"results.place_id"];

    //Iterator to iterate through the locations to see if the required place id is present in the Dictionary

    for (NSString *locationId in locations) {

        if ([placeId isEqualToString:locationId]){

            NSLog(@"Found The Matching LocationID");

            //predicate to iterate through all the places ids that match in order to access the entire object that has the location id so you can use it later onwards to access any part of the object (ratings, prices.... )
            NSPredicate *objectWithPlacesId = [NSPredicate predicateWithFormat:@"place_id == %@",locationId];

            //This array holds the entire object that contains the required place id
            NSArray *filteredArrayWithPlacesDetails = [[json objectForKey:@"results"] filteredArrayUsingPredicate:objectWithPlacesId];

            //Small question here if this is actually needed but i found it a problem to access the array as it returns a single object array
            NSDictionary *dictionaryWithDetails = [filteredArrayWithPlacesDetails firstObject];

            NSArray *photosArray = [dictionaryWithDetails valueForKeyPath:@"photos.photo_reference"];
            //NSString photo refence is accessed here , single object array so the first index always contain the photoReference
            NSString *photo_Reference = [photosArray objectAtIndex:0];

            //Create the Image Url , you can even format the max width and height the same way using %f
            NSString *imageUrl = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=%@&key=%@",photo_Reference,kGOOGLE_API_KEY];

            //Assing the image request for the sd_setImageWithURL to access the remote image
            [self.imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl]
                              placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

            break;
        }

        else{
            NSLog(@"Not Matching");
        }



    }

}