1. Install CocoaPods as the dependency manager.
Type this command in the terminal:
sudo gem install cocoapods
2. Create a Single View Application project with Xcode and close it.
3. Go to the Xcode project directory in the terminal, type pod init or nano Podfile to create a Podfile and save it as:
platform :ios, '9.0'
target "ProjectName" do
target "ProjectName" do
pod 'GoogleMaps'
pod 'Google-Maps-iOS-Utils'
end
4. Type this terminal command:
pod install
You should see something like this in the terminal:
If your GoogleMaps is an old version, update it with this terminal command:
pod update
5. Open the projectName.xcworkspace file just automatically created. (Don't open the original .xcodeproj file)
6. Add a temporary Objective-C file to your project. You may give it any name you like, e.g. Temp.m.
Select Create Bridging Header.
7. Delete the temporary Objective-C file (Temp.m) you just created.
8. In the projectName-Bridging-Header.h file just created, add this line:
9. Get the iOS API key like AIza................... from Google Developers Console. (For more details, see Step 6 of the Using Google Maps SDK for iOS in Swift tutorial.
10. Edit the AppDelegate.swift file:
13. Run the code. You should see result like this:
15. Try tap at different locations on the map to add new markers:
Related Information:
Marker Clustering
Google-Maps-iOS-Utils(GitHub)
Google Maps SDK for iOS
CocoaPods Tutorial - Google Maps SDK for iOS
4. Type this terminal command:
pod install
You should see something like this in the terminal:
pod update
5. Open the projectName.xcworkspace file just automatically created. (Don't open the original .xcodeproj file)
6. Add a temporary Objective-C file to your project. You may give it any name you like, e.g. Temp.m.
Select Create Bridging Header.
7. Delete the temporary Objective-C file (Temp.m) you just created.
8. In the projectName-Bridging-Header.h file just created, add this line:
#import <Google-Maps-iOS-Utils/GMUMarkerClustering.h>
9. Get the iOS API key like AIza................... from Google Developers Console. (For more details, see Step 6 of the Using Google Maps SDK for iOS in Swift tutorial.
10. Edit the AppDelegate.swift file:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
GMSServices.provideAPIKey("AIza....") //iOS API key
return true
}
10. Modify ViewController.swift as below:
The above code is modified from Google's ViewController.swift of the SwiftDemoApp.
11. Add the file image files below to the Xcode project:
https://github.com/googlemaps/google-maps-ios-utils/tree/master/app/Resources/Images
12. Edit the Info.plist file (Required for Xcode 7 and iOS 9):
Key: LSApplicationQueriesSchemes
Type: Array
Key: Item 0
Type: String
Value: googlechromes
Key: Item 1
Type: String
Value: comgooglemaps
Without modifying Info.plist, you'll get
Pressing the Google logo on the map in the iOS simulator shows:
This is because the iOS simulator does not include Google Maps and Chrome apps. So check this feature with a device.
import UIKit
class ViewController: UIViewController, GMSMapViewDelegate, GMUClusterManagerDelegate {
private var mapView : GMSMapView!
private var clusterManager: GMUClusterManager!
//true - marker clustering / false - map markers without clustering
let isClustering : Bool = true
//true - images / false - default icons
let isCustom : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
mapView = GMSMapView(frame: view.frame)
//Default position at Chungli (Zhongli) Railway Station, Taoyuan, Taiwan.
mapView.camera = GMSCameraPosition.cameraWithLatitude(24.953232, longitude: 121.225353, zoom: 12.0)
mapView.mapType = kGMSTypeNormal
mapView.delegate = self
view.addSubview(mapView)
if isClustering {
var iconGenerator : GMUDefaultClusterIconGenerator!
if isCustom {
var images : [UIImage] = []
for imageID in 1...5 {
images.append(UIImage(named: "m\(imageID).png")!)
}
iconGenerator = GMUDefaultClusterIconGenerator(buckets: [ 10, 50, 100, 200, 500 ], backgroundImages: images)
} else {
iconGenerator = GMUDefaultClusterIconGenerator()
}
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
generateCoord(true)
// Call cluster() after items have been added to perform the clustering and rendering on map.
clusterManager.cluster()
// Register self to listen to both GMUClusterManagerDelegate and GMSMapViewDelegate events.
clusterManager.setDelegate(self, mapDelegate: self)
} else {
generateCoord(false)
}
}
/// Point of Interest Item which implements the GMUClusterItem protocol.
class POIItem: NSObject, GMUClusterItem {
var position: CLLocationCoordinate2D
var name: String!
init(position: CLLocationCoordinate2D, name: String) {
self.position = position
self.name = name
}
}
func generateCoord(isCluster: Bool) {
let latitudeMin : Double = 24.79
let latitudeMax : Double = 25.10
let latitudeDiff : Double = latitudeMax - latitudeMin
let longitudeMin : Double = 120.99
let longitudeMax : Double = 121.50
let longitudeDiff : Double = longitudeMax - longitudeMin
for count in 1...5000 {
let latitude = latitudeMin + Double(arc4random()%10000)/10000*latitudeDiff
let longitude = longitudeMin + Double(arc4random()%10000)/10000*longitudeDiff
let position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
if isCluster {
let item = POIItem(position: position, name: "#\(count)")
clusterManager.addItem(item)
} else {
let marker = GMSMarker(position: position)
marker.title = "#\(count)"
marker.map = mapView
}
}
}
func clusterManager(clusterManager: GMUClusterManager, didTapCluster cluster: GMUCluster) {
let newCamera = GMSCameraPosition.cameraWithTarget(cluster.position,
zoom: mapView.camera.zoom + 1)
let update = GMSCameraUpdate.setCamera(newCamera)
mapView.moveCamera(update)
}
//Show the marker title while tapping
func mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) -> Bool {
let item : POIItem = marker.userData as! POIItem
marker.title = item.name
mapView.selectedMarker = marker
return true
}
//Optional Feature:
//Add new markers while tapping at coordinates without markers/clusters
func mapView(mapView: GMSMapView, didTapAtCoordinate coordinate: CLLocationCoordinate2D) {
let item = POIItem(position: coordinate, name: "NEW")
clusterManager.addItem(item)
clusterManager.cluster()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
The above code is modified from Google's ViewController.swift of the SwiftDemoApp.
11. Add the file image files below to the Xcode project:
https://github.com/googlemaps/google-maps-ios-utils/tree/master/app/Resources/Images
12. Edit the Info.plist file (Required for Xcode 7 and iOS 9):
Key: LSApplicationQueriesSchemes
Type: Array
Key: Item 0
Type: String
Value: googlechromes
Key: Item 1
Type: String
Value: comgooglemaps
Without modifying Info.plist, you'll get
Pressing the Google logo on the map in the iOS simulator shows:
-canOpenURL: failed for URL: "comgooglemaps://" - error: "This app is not allowed to query for scheme comgooglemaps"
-canOpenURL: failed for URL: "googlechromes://" - error: "This app is not allowed to query for scheme
This is because the iOS simulator does not include Google Maps and Chrome apps. So check this feature with a device.
13. Run the code. You should see result like this:
14. Set isCustom as true to see the custom clustering images:
//true - images / false - default icons
let isCustom : Bool = true
15. Try tap at different locations on the map to add new markers:
Related Information:
Marker Clustering
Google-Maps-iOS-Utils(GitHub)
Google Maps SDK for iOS
CocoaPods Tutorial - Google Maps SDK for iOS