Xcode 프로젝트 설정

결제를 사용 설정하고 API 키를 만든 후 앱 개발에 사용할 Xcode 프로젝트를 설정할 수 있습니다.

각 출시 버전의 출시 노트를 확인할 수 있습니다.

1단계: 필수 소프트웨어 설치하기

iOS용 Places SDK를 사용하여 프로젝트를 빌드하려면 다음이 필요합니다.

  • Xcode 버전 15.0 이상

2단계: Xcode 프로젝트 생성 및 iOS용 Places SDK 설치

Swift Package Manager

iOS용 Places SDK는 Swift Package Manager를 통해 설치할 수 있습니다. SDK를 추가하려면 기존의 iOS용 Places SDK 종속 항목을 모두 삭제해야 합니다.

새 프로젝트 또는 기존 프로젝트에 SDK를 추가하려면 다음 단계를 따르세요.

  1. Xcode project 또는 workspace를 열고 File(파일) > Add Package Dependencies(패키지 종속 항목 추가)로 이동합니다.
  2. URL에 https://github.com/googlemaps/ios-places-sdk를 입력하고 Enter 키를 눌러 패키지를 가져온 후 '패키지 추가'를 클릭합니다.
  3. 특정 version를 설치하려면 종속 항목 규칙 필드를 버전 기반 옵션 중 하나로 설정합니다. 새 프로젝트의 경우 최신 버전을 지정하고 '정확한 버전' 옵션을 사용하는 것이 좋습니다. 완료되면 'Add Package'를 클릭합니다.
  4. Choose Package Products 창에서 GooglePlaces이 지정된 main 타겟에 추가되는지 확인합니다. 완료되면 'Add Package'를 클릭합니다.
  5. 설치를 확인하려면 대상의 General 창으로 이동합니다. 프레임워크, 라이브러리 및 삽입된 콘텐츠에서 설치된 패키지를 확인할 수 있습니다. 'Project Navigator'의 'Package Dependencies' 섹션에서 패키지와 버전을 확인할 수도 있습니다.

기존 프로젝트의 package를 업데이트하려면 다음 단계를 따르세요.

  1. 9.0.0 이전 버전에서 업그레이드하는 경우 업그레이드 후 GoogleMapsBase, GoogleMapsCore, GoogleMapsM4B 종속 항목을 삭제해야 합니다. GoogleMaps의 종속 항목을 삭제하지 마세요. 자세한 내용은 버전 9.0.0 출시 노트를 참고하세요.

    Xcode 프로젝트 구성 설정에서 프레임워크, 라이브러리 및 삽입된 콘텐츠를 찾습니다. 빼기 기호(-)를 사용하여 다음 프레임워크를 삭제합니다.

    • GoogleMapsBase (9.0.0 이전 버전에서 업그레이드하는 경우에만)
    • GoogleMapsCore (9.0.0 이전 버전에서 업그레이드하는 경우에만)
    • GoogleMapsM4B (9.0.0 이전 버전에서 업그레이드하는 경우에만)
  2. Xcode에서 'File(파일) > Packages(패키지) > Update To Latest Package Versions(최신 패키지 버전으로 업데이트)'로 이동합니다.
  3. 설치를 확인하려면 Project NavigatorPackage Dependencies 섹션으로 이동하여 패키지와 버전을 확인하세요.

CocoaPods를 사용하여 추가된 기존 iOS용 Places SDK 종속 항목을 삭제하려면 다음 단계를 따르세요.

  1. Xcode 작업공간을 닫습니다. 터미널을 열고 다음 명령어를 실행합니다.
    sudo gem install cocoapods-deintegrate cocoapods-clean 
    pod deintegrate 
    pod cache clean --all
  2. Podfile, Podfile.resolved, Xcode workspace를 CocoaPods 외에 다른 용도로 사용하지 않는다면 삭제합니다.

수동으로 설치된 기존 iOS용 Places SDK를 삭제하려면 다음 단계를 따르세요.
  1. Xcode 프로젝트 구성 설정에서 프레임워크, 라이브러리 및 삽입된 콘텐츠를 찾습니다. 빼기 기호(-)를 사용하여 다음 프레임워크를 삭제합니다.
    • GooglePlaces.xcframework
  2. Xcode 프로젝트의 최상위 디렉터리에서 GooglePlaces 번들을 삭제합니다.

CocoaPods

iOS용 Places SDK는 모든 장소 기능이 포함된 CocoaPod 포드인 GooglePlaces로 제공됩니다.

CocoaPods는 Swift 및 Objective-C Cocoa 프로젝트용 오픈소스 종속 항목 관리자입니다. CocoaPods 도구가 아직 없다면 터미널에서 다음 명령어를 실행하여 macOS에 설치합니다. 자세한 내용은 CocoaPods 시작 가이드를 참고하세요.

sudo gem install cocoapods

iOS용 Places SDK의 Podfile를 만들고 이를 사용하여 SDK와 종속 항목을 설치합니다.

  1. 아직 Xcode 프로젝트가 없으면 지금 만들어 로컬 시스템에 저장합니다. iOS 개발을 처음 접하는 경우 새 프로젝트를 만들고 iOS 앱 템플릿을 선택합니다.
  2. 프로젝트 디렉터리에 Podfile 파일을 만듭니다. 이 파일은 프로젝트의 종속 항목을 정의합니다.
  3. Podfile를 수정하고 versions과 함께 종속 항목을 추가합니다. 다음은 애플리케이션 대상 이름과 GooglePlaces 포드의 이름을 지정하는 예시입니다.
    source 'https://github.com/CocoaPods/Specs.git'
    
    platform :ios, '15.0'
    
    target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
      pod 'GooglePlaces', '8.3.0'
    end
    
    정기적으로 pod outdated를 실행하여 최신 버전이 있는지 감지하여 항상 최신 버전을 유지해야 합니다.
  4. Podfile을 저장합니다.
  5. 터미널을 열고 Podfile이 포함된 디렉터리로 이동합니다.

    cd <path-to-project>
  6. pod install 명령어를 실행합니다. Podfile에 지정된 API가 API에 포함된 종속 항목과 함께 설치됩니다.

    pod install
  7. Xcode를 닫은 다음 프로젝트의 .xcworkspace 파일을 (더블클릭하여) 열어 Xcode를 실행합니다. 이 때부터는 .xcworkspace 파일을 사용하여 프로젝트를 열어야 합니다.

기존 프로젝트의 API를 업데이트하려면 다음 단계를 따르세요.

  1. 터미널을 열고 Podfile가 포함된 프로젝트 디렉터리로 이동합니다.
  2. pod update 명령어를 실행합니다. 이렇게 하면 Podfile에 지정된 모든 API가 최신 버전으로 업데이트됩니다.

수동 설치

이 가이드에서는 iOS용 Places SDK가 포함된 XCFramework를 프로젝트에 수동으로 추가하고 Xcode에서 빌드 설정을 구성하는 방법을 설명합니다. XCFramework는 Apple Silicon을 사용하는 머신을 포함한 여러 플랫폼에서 사용할 수 있는 바이너리 패키지입니다.

  1. 다음 SDK 바이너리 및 리소스 파일을 다운로드합니다.
  2. 파일의 압축을 풀어 XCFramework 및 리소스에 액세스합니다.
  3. Xcode를 실행하고 기존 프로젝트를 열거나 새 프로젝트를 만듭니다. iOS 개발이 처음인 경우 새 프로젝트를 만들고 iOS 앱 템플릿을 선택합니다.
  4. 프로젝트의 이전 릴리스에서 모든 Maps 번들을 삭제합니다.
  5. 일반 탭을 엽니다. 다음 XCFramework를 프레임워크, 라이브러리 및 삽입된 콘텐츠 아래의 프로젝트로 드래그합니다. 퍼가기 허용 안 함을 선택해야 합니다.
    • GooglePlaces.xcframework
  6. 다운로드한 GooglePlacesResources에서 GooglePlaces.bundle을(를) 드래그합니다.
  7. 다운로드한 GooglePlacesResourcesGooglePlaces.bundle를 Xcode 프로젝트의 최상위 디렉터리에 복사합니다. 메시지가 표시되면 항목을 대상 그룹 폴더에 복사를 선택해야 합니다.
  8. Project Navigator에서 프로젝트를 선택하고 애플리케이션의 대상을 선택합니다.
  9. Build Phases 탭을 엽니다. 바이너리를 라이브러리와 연결 내에서 다음 프레임워크와 라이브러리를 추가합니다.
    • CoreGraphics.framework
    • CoreLocation.framework
    • libc++.tbd
    • libz.tbd
    • QuartzCore.framework
    • UIKit.framework
  10. 특정 타겟 대신 프로젝트를 선택하고 Build Settings 탭을 엽니다. 연결 - 일반 -> 기타 링커 플래그 섹션에서 '디버그' 및 '릴리스'에 -ObjC를 추가합니다. 이러한 설정이 표시되지 않으면 Build Settings 표시줄의 필터를 Basic에서 All로 변경합니다.

GooglePlacesSwift

Swift Package Manager, CocoaPods를 사용하여 GooglePlacesSwift (미리보기) SDK를 직접 설치할 수 있습니다. 모든 프로세스의 설치 단계는 iOS용 Places SDK에 설명된 단계와 동일하지만 다음과 같은 차이점이 있습니다.

예를 들어 CocoaPods를 사용하는 경우 수정된 Podfile는 다음과 같습니다.

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '15.3'

target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
  pod 'GooglePlacesSwift', '0.1.0'
end

3단계: Apple 개인 정보 보호 매니페스트 파일 검사하기

Apple은 App Store의 앱에 대한 앱 개인 정보 보호 세부정보를 요구합니다. 업데이트 및 자세한 내용은 Apple App Store 개인 정보 보호 세부정보 페이지를 참고하세요.

Apple 개인 정보 보호 매니페스트 파일은 SDK의 리소스 번들에 포함되어 있습니다. 개인 정보 보호 매니페스트 파일이 포함되었는지 확인하고 콘텐츠를 검사하려면 앱의 보관 파일을 만들고 보관 파일에서 개인 정보 보호 보고서를 생성하세요.

4단계: 앱에 API 키 추가

다음 예에서 YOUR_API_KEY를 이 API 키로 바꾸세요.

Swift

다음과 같이 API 키를 AppDelegate.swift에 추가합니다.

  • 다음 import 문을 추가합니다.
    import GooglePlaces
  • 다음을 application(_:didFinishLaunchingWithOptions:) 메서드에 추가하여 YOUR_API_KEY를 API 키로 바꿉니다.
    GMSPlacesClient.provideAPIKey("YOUR_API_KEY")

Objective-C

다음과 같이 API 키를 AppDelegate.m에 추가합니다.

  • 다음 import 문을 추가합니다.
    @import GooglePlaces;
  • 다음을 application:didFinishLaunchingWithOptions: 메서드에 추가하여 YOUR_API_KEY를 API 키로 바꿉니다.
    [GMSPlacesClient provideAPIKey:@"YOUR_API_KEY"];

GooglePlacesSwift

다음과 같이 API 키를 AppDelegate.swift에 추가합니다.

  • 다음 import 문을 추가합니다.
    import GooglePlacesSwift
  • 다음을 application(_:didFinishLaunchingWithOptions:) 메서드에 추가하여 YOUR_API_KEY를 API 키로 바꿉니다.
    PlacesClient.shared.provideAPIKey("YOUR_API_KEY")

5단계: 코드 작성 시작

다음 코드 샘플은 현재 장소를 가져오는 방법을 보여줍니다.

Swift

  import GooglePlaces
  import UIKit

  class GetStartedViewController : UIViewController {

    // Add a pair of UILabels in Interface Builder, and connect the outlets to these variables.
    @IBOutlet private var nameLabel: UILabel!
    @IBOutlet private var addressLabel: UILabel!

    private var placesClient: GMSPlacesClient!

    override func viewDidLoad() {
      super.viewDidLoad()
      placesClient = GMSPlacesClient.shared()
    }

    // Add a UIButton in Interface Builder, and connect the action to this function.
    @IBAction func getCurrentPlace(_ sender: UIButton) {
      let placeFields: GMSPlaceField = [.name, .formattedAddress]
      placesClient.findPlaceLikelihoodsFromCurrentLocation(withPlaceFields: placeFields) { [weak self] (placeLikelihoods, error) in
        guard let strongSelf = self else {
          return
        }

        guard error == nil else {
          print("Current place error: \(error?.localizedDescription ?? "")")
          return
        }

        guard let place = placeLikelihoods?.first?.place else {
          strongSelf.nameLabel.text = "No current place"
          strongSelf.addressLabel.text = ""
          return
        }

        strongSelf.nameLabel.text = place.name
        strongSelf.addressLabel.text = place.formattedAddress
      }
    }
  }

  

Objective-C

  #import "GetStartedViewController.h"
  @import GooglePlaces;

  @interface GetStartedViewController ()
  // Add a pair of UILabels in Interface Builder and connect the outlets to these variables
  @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
  @property (weak, nonatomic) IBOutlet UILabel *addressLabel;
  @end

  @implementation GetStartedViewController {
    GMSPlacesClient *_placesClient;
  }

  - (void)viewDidLoad {
    [super viewDidLoad];
    _placesClient = [GMSPlacesClient sharedClient];
  }

  // Add a pair of UILabels in Interface Builder and connect the outlets to these variables.
  - (IBAction)getCurrentPlace:(UIButton *)sender {
    GMSPlaceField placeFields = (GMSPlaceFieldName | GMSPlaceFieldFormattedAddress);

    __weak typeof(self) weakSelf = self;
    [_placesClient findPlaceLikelihoodsFromCurrentLocationWithPlaceFields:placeFields callback:^(NSArray<GMSPlaceLikelihood *> * _Nullable likelihoods, NSError * _Nullable error) {
      __typeof__(self) strongSelf = weakSelf;
      if (strongSelf == nil) {
        return;
      }

      if (error != nil) {
        NSLog(@"An error occurred %@", [error localizedDescription]);
        return;
      }

      GMSPlace *place = likelihoods.firstObject.place;
      if (place == nil) {
        strongSelf.nameLabel.text = @"No current place";
        strongSelf.addressLabel.text = @"";
        return;
      }

      strongSelf.nameLabel.text = place.name;
      strongSelf.addressLabel.text = place.formattedAddress;
    }];
  }

  @end
  

GooglePlacesSwift

  struct ContentView: View {
    @State var place: Place?

    var body: some View {
      Button("Get Place") {
        // A hotel in Saigon with an attribution.
        let placeID = "ChIJV4k8_9UodTERU5KXbkYpSYs"
        let fetchPlaceRequest = FetchPlaceRequest(
          placeID: placeID,
          placeProperties: [.displayName, .formattedAddress]
        )
        Task {
          switch await placesClient.fetchPlace(with: fetchPlaceRequest) {
          case .success(let place):
            self.place = place
          case .failure(let placesError):
            // Handle error
        }
      Text(swiftPlace?.displayName ?? "No place yet")
        .padding()
      Text(swiftPlace?.formattedAddress ?? "No place yet")
        .padding()
    }
  }
  

다음 단계

프로젝트가 구성되면 샘플 앱을 살펴볼 수 있습니다.