Places SDK for iOS (Objective-C) 使用入门

1. 准备工作

在开始编码之前,需要满足几个前提条件。

Xcode

本教程使用 Apple 的 Xcode 工具以及 Objective-C 语言来创建在模拟器中运行的简单 iOS 应用。您不需要使用真机设备。您可以从 https://developer.apple.com/xcode/

CocoaPods

Places SDK for iOS 作为 CocoaPods pod 提供。CocoaPods 是一种用于 Swift 和 Objective-C 项目的开源依赖项管理工具。如果您还没有此工具,则需要先安装,然后才能继续。它可以从终端安装,如下所示:

sudo gem install cocoapods

如需详细了解 CocoaPods,请参阅 CocoaPods 入门指南

安装 SDK

如需安装该 SDK,您需要在项目目录中创建一个 Podfile,CocoaPods 将用它来下载和配置必要的依赖项。最简单的方法是在 Xcode 中创建一个新项目,向其中添加 Podfile,然后在那里安装 pod。

打开 Xcode,您会看到“Welcome to Xcode'”屏幕。在此处,选择“Create a new Xcode project'

4f1ecee473937c7b.png

在下一个屏幕上,系统会要求您提供新项目的模板。选择“Single View Application”(适用于 iOS),然后按“Next'

当系统要求您提供产品名称时,您可以选择任意名称,但请务必记下系统为您生成的软件包标识符。您稍后将需要使用此信息。

72fbf25cb2db22ad.png

按“Next”,系统将为您创建项目。记下创建该目录的目录。关闭 Xcode,然后使用终端导航到该目录。

使用终端,输入以下命令:

pod init

系统将为您创建一个名为 Podfile 的文件。对其进行修改,为 GoogleMaps 添加 Pod,如下所示:

target '{YOUR APP NAME}' do
pod 'GoogleMaps'
end

保存该文件,然后关闭 Xcode。请务必将其关闭,因为在下一步中,您需要修改底层项目。项目完成后,您将打开不同的项目文件,如果开发者之前没有关闭 Xcode,会很困惑,因为所有内容都在哪里,现在,在终端中,转到您的项目目录并运行“pod install&#39”,如下所示:

789c5bc62817f68a.png

完成后,系统将安装 pod 并创建新的 .xcworkspace 文件。从现在起,请在项目中使用此方法。但在编码之前,接下来您需要一个 API 密钥。

2. 获取 API 密钥

为了完成以下启用步骤,请启用 Maps SDK for iOS

设置 Google Maps Platform

如果您还没有已启用结算功能的 Google Cloud Platform 帐号和项目,请参阅 Google Maps Platform 使用入门指南,创建结算帐号和项目。

  1. Cloud Console 中,点击项目下拉菜单,选择要用于此 Codelab 的项目。

  1. Google Cloud Marketplace 中启用此 Codelab 所需的 Google Maps Platform API 和 SDK。为此,请按照此视频此文档中的步骤操作。
  2. 在 Cloud Console 的凭据页面中生成 API 密钥。您可以按照此视频此文档中的步骤操作。向 Google Maps Platform 发出的所有请求都需要 API 密钥。

3.创建 Places API 应用

现在,您已创建了一个控制台项目,并在其中激活了 Places API 并获取 API 密钥,接下来就可以开始编写您的第一个 Places API 应用了。

安装 pod 文件时,系统已为您创建一个新的 .xcworkspace 文件。双击它将其打开。

19d62f34c08e645c.png

您将在 Project Explorer 中发现,现在有一个名为“Pods'”的新文件夹。如果此操作成功,您会在其中看到一个包含这些框架的 GoogleMaps 文件夹。

8844d861f64c61aa.png

4.修改 Info.plist 文件。

当您首次运行应用时,iOS 会向您显示一个对话框,请求用户授予访问位置服务的权限。此对话框会提供一个您所定义的字符串,并将其放入 Info.plist 文件中。如果此字符串不存在,对话框不会显示,您的应用也无法运行。

您可以在 Project Explorer 中找到 Info.plist 文件,方法如下:

c224c920ab3f1ef.png

选择该窗口,您将看到 plist 编辑器。

859ca56f3b19da5.png

将鼠标悬停在任意元素上,就会显示“+”图标。按此按钮,系统会显示一个新条目。在此框中输入值“NSLocationAlwaysUsageDescription'”。

9fb225d6f5508794.png

按 Enter 键即可添加新键。然后双击此键的“值”列,并添加一个字符串:

5aefeb184187aa58.png

如需详细了解此字符串,请点击此处查看 Apple 开发者文档。

5. 修改应用委托

在 Project Explorer 中,找到并打开 AppDelegate.m。您将使用该 API 密钥添加 API 密钥。

在文件顶部,将以下代码添加到 #import 行下方:

@import GoogleMaps;

然后,在 didFinishLaunchingWithOptions: 函数中,添加下面关于“返回 YES' 行”的内容:

[GMSServices provideAPIKey:@"<Add your API Key>"];

请务必使用您之前生成的 API 密钥。

6. 编辑故事板文件

在 Project Explorer 中,打开 Main.storyboard 文件。按右上角的边栏按钮,确保侧边栏处于活动状态。

352af28b970d9e2.png

然后,在边栏底部,通过选择对象库找到“标签控件”。

adec7051ae949531.png

在左侧的视图控制器场景中,确保已选择“View&#39”:

e4827b92b5861e3e.png

然后,将 7 个标签拖放到视图中。请按此处所示对它们进行排序。请确保拖动图片的尺寸以与所显示的图片相符。您可以双击标签中的文本并键入所需的值,从而对其进行修改:

f8a9457772358069.png

对于最底部的标签(非常大的标签),请转到属性编辑器,确保将其设置为 0 行(默认值为 1)。以便能渲染多行。

a4abacf00d8888fe.png

7. 为值创建输出口

对于 3 个“value”标签,您需要创建一个插座。这样,您就可以使用代码更改它们的值。为此,你需要先激活助理编辑器。为此,请先点击属性边栏的按钮,将其移除。(在上一步中显示此按钮)

然后,选择辅助按钮 - 即如下所示的双圆圈:

e92dcc4ceea20a51.png

请确保该文件能够渲染 ViewController.h 文件。否则,您可以使用 Google 助理窗口顶部的编辑器进行更改:

d42f0fcc18b84703.png

然后,在按住 CONTROL 键时,将每个标签拖放到 Google 助理的 ViewController.h 文件中的 @interface 行的下方。系统会弹出一个对话框,询问您要建立哪种类型的连接:

a44b7888ed0f62b.png

请确保设置如图所示(连接:输出口;类型:界面标签;存储:弱),然后为每个设置命名。在此 Codelab 中,我分别将经度、纬度和海拔高度标签分别命名为 lblLongitude、lblLatitude 和 lblAltidude。此外,将大标签从底部拖出并命名为 lblPlaces。

完成后,您的 ViewController.h 文件应如下所示:

#import <UIKit/UIKit.h>
@import GoogleMaps;

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *lblLatitude;
@property (weak, nonatomic) IBOutlet UILabel *lblLongitude;
@property (weak, nonatomic) IBOutlet UILabel *lblAltitude;
@property (weak, nonatomic) IBOutlet UILabel *lblPlaces;

@end

8. 修改 Location API 和 Google Client API 的头文件

在最后一步(也就是构建应用以使用 Places API)之前,您需要在头文件 (ViewController.h) 中设置一些其他变量。这些是 Core Location Manager 和 Core Location 对象:

@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *location;

您还需要一个 Google API 客户端:

@property GMSPlacesClient *placesClient;

最后,您需要更新头文件,以便该类实现 CLLocationManagerDelegate:

@interface ViewController : UIViewController<CLLocationManagerDelegate>

完成后,您的头文件应如下所示:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <GoogleMaps/GoogleMaps.h>


@interface ViewController : UIViewController<CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *location;
@property (weak, nonatomic) IBOutlet UILabel *lblLongitude;
@property (weak, nonatomic) IBOutlet UILabel *lblLatitude;
@property (weak, nonatomic) IBOutlet UILabel *lblAltitude;
@property (weak, nonatomic) IBOutlet UILabel *lblPlaces;

@property GMSPlacesClient *placesClient;
@end

9. 修改视图控制器

第一步是修改 viewDidLoad 函数以初始化位置管理器,请求用户授予位置访问权限,最后启动位置管理器,以便跟踪当前位置。您还将初始化 Google Places API 客户端。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc]init];
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
        // Or [self.locationManager requestWhenInUseAuthorization];
    }
    [self.locationManager startUpdatingLocation];
    
    self.locationManager.delegate = self;
    self.location = [[CLLocation alloc] init];
    self.placesClient = [GMSPlacesClient sharedClient];
}

10. 处理位置信息更新

位置信息管理器会调用 didUpdateLocations 函数,并使用位置信息更新回调您的视图控制器。您需要将此代码添加到您的 ViewController.m 中。该函数如下所示:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    // Enter code here
}

此函数需要执行多项操作。

首先,它会使用最后收到的一个位置缓存位置:

self.location = locations.lastObject;

接下来,应更新“纬度”、“经度”和“海拔高度”的三个标签:

self.lblLatitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];

self.lblLongitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];

self.lblAltitude.text = [NSString stringWithFormat:@"%f", self.location.altitude];

接下来,您将使用 Places Client 调用 Places API。为此,您可以指定回调函数,该函数将获取地点可能性列表。Places API 会根据您所在的位置确定您位于特定地点的可能性。它会返回可能的地点的名称,以及 0 到 1 之间的值,该值表示您位于该地点的可能性。

[self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

然后,您就可以实现回调。这将遍历可能性列表,为这些地点添加地点和可能性。

[self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

  if (error != nil) {
    NSLog(@"Current Place error %@", [error localizedDescription]);
    return;
  }
  NSMutableString *strPlaces = [NSMutableString stringWithString:@""];

  for (GMSPlaceLikelihood *likelihood in likelihoodList.likelihoods) {
    GMSPlace* place = likelihood.place;
    NSLog(@"Current Place name %@ at likelihood %g", place.name,
            likelihood.likelihood);
    NSLog(@"Current Place address %@", place.formattedAddress);
    NSLog(@"Current Place attributions %@", place.attributions);
    NSLog(@"Current PlaceID %@", place.placeID);
    [strPlaces appendString:place.name];
    [strPlaces appendString:@" "];
    [strPlaces appendFormat:@"%g",likelihood.likelihood];
    [strPlaces appendString:@"\n"];
  }
  self.lblPlaces.text = strPlaces;
}];

完成后,您的 didUpdateLocations 函数应如下所示:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    
    self.location = locations.lastObject;
    self.lblLatitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];
    self.lblLongitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];
    self.lblAltitude.text = [NSString stringWithFormat:@"%f", self.location.altitude];
    
    NSLog(@"%@", self.location.description);
    
    [self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

        if (error != nil) {
            NSLog(@"Current Place error %@", [error localizedDescription]);
            return;
        }
        NSMutableString *strPlaces = [NSMutableString stringWithString:@""];
        
        for (GMSPlaceLikelihood *likelihood in likelihoodList.likelihoods)  
        {
            GMSPlace* place = likelihood.place;
            NSLog(@"Current Place name %@ at likelihood %g", place.name, likelihood.likelihood);
            NSLog(@"Current Place address %@", place.formattedAddress);
            NSLog(@"Current Place attributions %@", place.attributions);
            NSLog(@"Current PlaceID %@", place.placeID);
            [strPlaces appendString:place.name];
            [strPlaces appendString:@" "];
            [strPlaces appendFormat:@"%g",likelihood.likelihood];
            [strPlaces appendString:@"\n"];
        }
        self.lblPlaces.text = strPlaces;
    }];
}

现在,您可以运行应用并进行测试了!

11. 在模拟器中运行应用

您可以使用标题栏中的“运行”按钮运行应用。这样还可以选择运行类型,正如您在此处看到的,使用模拟器在 iPhone 6 上进行测试。

bbbe0b8820c8a913.png

当您按运行按钮时,应用将构建并启动。您会看到允许应用获取位置信息的请求,包括您之前指定的自定义字符串。

b9bb2ace7e68f186.png

执行此操作后,您的纬度和经度将会更新。要更改位置,请选择“调试”菜单,然后选择一个位置。例如,您可以选择“快速路”

dcb1ce091d780f56.png

当您进行模拟时,您会看到该地点及其可能更新的地点,模拟高速公路行驶。

649e3eeb2321ae03.png

这样就大功告成了!您已在 iOS 上使用 Google Places API 成功访问了当前的地点详情。