1. Zanim zaczniesz
Zanim zaczniesz pisać kod, musisz spełnić kilka wymagań wstępnych.
Xcode
W tym samouczku używamy narzędzia Xcode firmy Apple oraz języka Objective-C do utworzenia prostej aplikacji na iOS, która działa w emulatorze. Nie potrzebujesz fizycznego urządzenia. Xcode możesz pobrać ze strony https://developer.apple.com/xcode/.
CocoaPods
Pakiet SDK Miejsc na iOS jest dostępny jako pod CocoaPods. CocoaPods to narzędzie open source do zarządzania zależnościami w projektach w językach Swift i Objective-C. Jeśli nie masz jeszcze tego narzędzia, musisz je zainstalować, zanim przejdziesz dalej. Możesz go zainstalować w terminalu w ten sposób:
sudo gem install cocoapods
Więcej informacji o CocoaPods znajdziesz w przewodniku CocoaPods Getting Started.
Instalowanie pakietu SDK
Aby zainstalować pakiet SDK, musisz utworzyć w katalogu projektu plik Podfile, którego CocoaPods użyje do pobrania i skonfigurowania wymaganych zależności. Najprostszym sposobem jest utworzenie nowego projektu w Xcode, dodanie do niego pliku Podfile i zainstalowanie w nim podów.
Otwórz Xcode. Zobaczysz ekran „Welcome to Xcode”. Kliknij „Utwórz nowy projekt w Xcode”.
Na następnym ekranie pojawi się prośba o wybranie szablonu nowego projektu. Wybierz „Single View Application” (Aplikacja z widokiem pojedynczym) dla iOS i kliknij „Next” (Dalej).
Gdy pojawi się prośba o podanie nazwy produktu, możesz wybrać dowolną nazwę, ale pamiętaj, aby zapisać wygenerowany identyfikator pakietu. Będzie Ci potrzebny później.
Kliknij „Dalej”, a projekt zostanie utworzony. Zanotuj katalog, w którym został utworzony. Zamknij Xcode i za pomocą Terminala przejdź do tego katalogu.
W terminalu wpisz to polecenie:
pod init
Zostanie utworzony plik o nazwie Podfile. Edytuj go, aby dodać pod do Google Maps, np. tak:
target '{YOUR APP NAME}' do
pod 'GoogleMaps'
end
Zapisz go i zamknij Xcode. Zamknij go, ponieważ w następnym kroku będziesz edytować projekt bazowy. Po zakończeniu tego procesu otworzysz inny plik projektu. Jeśli deweloper nie zamknie wcześniej Xcode, może się pomylić co do lokalizacji poszczególnych elementów. Teraz w terminalu przejdź do katalogu projektu i uruchom polecenie „pod install” w ten sposób:
Po zakończeniu instalacji podów zostanie utworzony nowy plik .xcworkspace. Od teraz używaj go w projekcie. Zanim jednak zaczniesz pisać kod, musisz uzyskać klucz interfejsu API.
2. Uzyskiwanie klucza interfejsu API
W kolejnym kroku włącz Maps SDK na iOS.
Konfigurowanie Google Maps Platform
Jeśli nie masz jeszcze konta Google Cloud Platform i projektu z włączonymi płatnościami, zapoznaj się z przewodnikiem Pierwsze kroki z Google Maps Platform, aby utworzyć konto rozliczeniowe i projekt.
- W konsoli Google Cloud kliknij menu projektu i wybierz projekt, którego chcesz użyć w tym samouczku.
- Włącz interfejsy API i pakiety SDK Google Maps Platform wymagane w tym samouczku w Google Cloud Marketplace. Aby to zrobić, wykonaj czynności opisane w tym filmie lub tej dokumentacji.
- Wygeneruj klucz interfejsu API na stronie Dane logowania w konsoli Cloud. Możesz wykonać czynności opisane w tym filmie lub tej dokumentacji. Wszystkie żądania wysyłane do Google Maps Platform wymagają klucza interfejsu API.
3. Tworzenie aplikacji Places API
Po utworzeniu projektu w konsoli i włączeniu w nim interfejsu Places API możesz uzyskać klucz interfejsu API i zacząć pisać pierwszą aplikację korzystającą z interfejsu Places API.
Wcześniej podczas instalowania plików pod utworzyliśmy dla Ciebie nowy plik .xcworkspace. Otwórz go, klikając dwukrotnie.
W Eksploratorze projektu zobaczysz nowy folder o nazwie „Pods”. Jeśli operacja się powiedzie, w tym folderze zobaczysz folder GoogleMaps zawierający platformy.
4. Edytuj plik Info.plist.
Gdy uruchomisz aplikację po raz pierwszy, iOS wyświetli okno z prośbą o zezwolenie na dostęp do usług lokalizacyjnych. W tym oknie pojawi się zdefiniowany przez Ciebie ciąg znaków, który należy umieścić w pliku Info.plist. Jeśli tego ciągu nie ma, okno dialogowe się nie wyświetli, a aplikacja nie będzie działać.
Plik Info.plist znajdziesz w eksploratorze projektu:
Wybierz go, a zobaczysz edytor pliku plist.
Najedź kursorem myszy na dowolny element, a zobaczysz ikonę „+”. Naciśnij go, a zobaczysz nowy wpis. Wpisz w tym polu wartość „NSLocationAlwaysUsageDescription”.
Aby dodać nowy klucz, naciśnij Enter. Następnie kliknij dwukrotnie kolumnę Wartość dla tego klucza i dodaj ciąg znaków:
Więcej informacji o tym ciągu znaków znajdziesz w dokumentacji dla programistów Apple tutaj.
5. Edytowanie delegata aplikacji
W eksploratorze projektu znajdź i otwórz plik AppDelegate.m. Użyjesz go do dodania klucza interfejsu API.
U góry pliku, bezpośrednio pod wierszem #import, dodaj ten kod:
@import GoogleMaps;
Następnie w funkcji didFinishLaunchingWithOptions: tuż przed wierszem „return YES” dodaj ten kod:
[GMSServices provideAPIKey:@"<Add your API Key>"];
Pamiętaj, aby użyć klucza interfejsu API wygenerowanego wcześniej.
6. Edytowanie pliku scenorysu
W eksploratorze projektu otwórz plik Main.storyboard. Upewnij się, że pasek boczny jest aktywny. W tym celu naciśnij przycisk paska bocznego w prawym górnym rogu.
Następnie u dołu paska bocznego znajdź element Label Control (Kontrolka etykiety). W tym celu upewnij się, że wybrana jest biblioteka obiektów.
W scenie kontrolera widoku po lewej stronie upewnij się, że wybrano „View” (Widok):
Następnie przeciągnij i upuść na widok 7 etykiet. Ułóż je tak, jak pokazano tutaj. Dopasuj ich rozmiary do tych, które są wyświetlane. Aby edytować tekst etykiety, kliknij ją dwukrotnie i wpisz odpowiednią wartość:
W przypadku etykiety znajdującej się na samym dole (tej bardzo dużej) otwórz edytor właściwości i upewnij się, że ma ona 0 wierszy (domyślnie jest to 1). Dzięki temu będzie można renderować wiele wierszy.
7. Tworzenie gniazd dla wartości
W przypadku 3 etykiet „value” musisz utworzyć punkt sprzedaży. Dzięki temu będziesz mieć możliwość zmiany ich wartości za pomocą kodu. Aby to zrobić, musisz najpierw aktywować edytora pomocniczego. Aby to zrobić, najpierw zamknij pasek boczny właściwości, klikając jego przycisk. (ten przycisk był widoczny w poprzednim kroku)
Następnie wybierz przycisk Asystenta – jest to podwójne kółko widoczne tutaj:
Sprawdź, czy renderuje plik ViewController.h. Jeśli nie, możesz to zmienić za pomocą edytora u góry okna asystenta:
Następnie przytrzymaj klawisz CONTROL i przeciągnij każdą etykietę, a potem upuść ją poniżej wiersza @interface w pliku ViewController.h w asystencie. Pojawi się okno z pytaniem, jakiego rodzaju połączenie chcesz nawiązać:
Sprawdź, czy ustawienia są takie jak na ilustracji (Connection: Outlet; Type: UILabel; Storage: Weak), a następnie nadaj każdemu z nich nazwę. Na potrzeby tego laboratorium nazwałem etykiety Długość geograficzna, Szerokość geograficzna i Wysokość odpowiednio lblLongitude, lblLatitude i lblAltidude. Przeciągnij też dużą etykietę z dołu i nazwij ją lblPlaces.
Gdy skończysz, plik ViewController.h powinien wyglądać tak:
#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. Edytowanie pliku nagłówkowego interfejsów API lokalizacji i Google Client
Przed wykonaniem ostatnich kroków, w których skompilujesz aplikację, aby korzystać z interfejsu Places API, musisz skonfigurować jeszcze kilka zmiennych w pliku nagłówkowym (ViewController.h). Są to Menedżer lokalizacji podstawowych i obiekt lokalizacji podstawowych:
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *location;
Potrzebny będzie też klient interfejsu API Google:
@property GMSPlacesClient *placesClient;
Na koniec musisz zaktualizować plik nagłówkowy, aby klasa implementowała protokół CLLocationManagerDelegate:
@interface ViewController : UIViewController<CLLocationManagerDelegate>
Gdy skończysz, plik nagłówkowy powinien wyglądać tak:
#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. Edytowanie kontrolera widoku
Pierwszym krokiem jest edytowanie funkcji viewDidLoad w celu zainicjowania menedżera lokalizacji, poproszenia użytkownika o autoryzację dostępu do lokalizacji i ostatecznego uruchomienia menedżera lokalizacji, aby śledził bieżącą lokalizację. Zainicjujesz też klienta interfejsu 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. Obsługa aktualizacji lokalizacji
Menedżer lokalizacji wywoła funkcję didUpdateLocations, aby przekazać do kontrolera widoku aktualizacje lokalizacji. Musisz dodać to do pliku ViewController.m. Funkcja wygląda tak:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
// Enter code here
}
Ta funkcja będzie musiała wykonać kilka czynności.
Najpierw zapisze w pamięci podręcznej lokalizację z ostatnio otrzymanymi danymi:
self.location = locations.lastObject;
Następnie należy zaktualizować 3 etykiety: szerokość geograficzna, długość geograficzna i wysokość:
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];
Następnie wywołasz interfejs Places API za pomocą klienta Places. Aby to zrobić, określ funkcję wywołania zwrotnego, która otrzyma listę prawdopodobieństw miejsc. Interfejs Places API określa prawdopodobieństwo, że znajdujesz się w danym miejscu, na podstawie Twojej lokalizacji. Zwraca nazwy prawdopodobnych miejsc wraz z wartością z zakresu od 0 do 1, która zawiera prawdopodobieństwo, że znajdujesz się w danym miejscu.
[self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {
Następnie możesz wdrożyć wywołanie zwrotne. Spowoduje to iterację po liście prawdopodobieństw, dodając miejsca i prawdopodobieństwa dla tych miejsc.
[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;
}];
Gdy skończysz, funkcja didUpdateLocations powinna wyglądać tak:
-(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;
}];
}
Możesz teraz uruchomić aplikację i ją przetestować.
11. Uruchamianie aplikacji w emulatorze
Aplikację uruchamiasz za pomocą przycisku uruchamiania na pasku tytułu. Możesz też wybrać typ uruchomienia. Jak widać, testuję na emulatorze iPhone'a 6.
Gdy naciśniesz przycisk uruchamiania, aplikacja zostanie skompilowana i uruchomiona. Zobaczysz prośbę o zezwolenie aplikacji na dostęp do lokalizacji, w tym niestandardowy ciąg znaków, który został wcześniej określony.
Gdy to zrobisz, zobaczysz zaktualizowane wartości szerokości i długości geograficznej. Aby zmienić lokalizację, wybierz menu Debuguj i kliknij lokalizację. Możesz na przykład wybrać „Freeway Drive”.
Gdy to zrobisz, zobaczysz lokalizację z aktualizującymi się prawdopodobnymi miejscami, co będzie symulować jazdę po autostradzie.
To wszystko. Udało Ci się uzyskać dostęp do szczegółów bieżącego miejsca za pomocą interfejsu Google Places API na iOS.