// AppDelegate.swiftimportUIKitimportReSwiftimportGoogleMaps// Storeの定義letmainStore=Store<AppState>(reducer:appReducer,state:nil)@UIApplicationMainclassAppDelegate:UIResponder,UIApplicationDelegate{varwindow:UIWindow?funcapplication(_application:UIApplication,didFinishLaunchingWithOptionslaunchOptions:[UIApplicationLaunchOptionsKey:Any]?)->Bool{// Override point for customization after application launch.// ここでGoogleマップの設定ifletpath=Bundle.main.path(forResource:"key",ofType:"plist"){ifletdic=NSDictionary(contentsOfFile:path)as?[String:Any]{ifletapiKey=dic["googleApiKey"]as?String{GMSServices.provideAPIKey(apiKey)}}}returntrue}...}
importUIKitimportGoogleMapsimportReSwiftclassViewController:UIViewController{// MARK: - IBOutlets@IBOutletweakvarmapView:GMSMapView!// MARK: - PropertiesprivatevarlocationManager:CLLocationManager?privateletzoomLevel:Float=16.0privatevarcurrentLocation:CLLocationCoordinate2D?privatevarinitView:Bool=falseoverridefuncviewDidLoad(){super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.// GoogleMapの初期化mapView.isMyLocationEnabled=truemapView.mapType=GMSMapViewType.normalmapView.settings.compassButton=truemapView.settings.myLocationButton=truemapView.settings.compassButton=truemapView.delegate=self// 位置情報関連の初期化locationManager=CLLocationManager()locationManager?.desiredAccuracy=kCLLocationAccuracyBestlocationManager?.requestWhenInUseAuthorization()locationManager?.startUpdatingLocation()locationManager?.delegate=self// subscribe to state changesmainStore.subscribe(self)}overridefuncdidReceiveMemoryWarning(){super.didReceiveMemoryWarning()// Dispose of any resources that can be recreated.}// MARK: - IBActions@IBActionfunctappedSearchButton(_sender:Any){mainStore.dispatch(MapState.fetchRestaurantsAction(lat:mapView.myLocation?.coordinate.latitude??0,lng:mapView.myLocation?.coordinate.longitude??0))}}// MARK: - OtherextensionViewController{/// GoogleMapにマーカをプロットする////// - Parameter place: プロットする場所情報privatefuncputMarker(place:Place){letmarker=GMSMarker()marker.position=CLLocationCoordinate2D(latitude:place.geometry.location.lat,longitude:place.geometry.location.lng)marker.icon=UIImage(named:"RestaurantIcon")marker.appearAnimation=GMSMarkerAnimation.popmarker.map=mapView}}// MARK: - StoreSubscriberextensionViewController:StoreSubscriber{typealiasStoreSubscriberStateType=AppStatefuncnewState(state:AppState){// when the state changes, the UI is updated to reflect the current stateguardleterror=state.mapState.errorelse{letplaces=state.mapState.placesifplaces.count==0{mapView.clear()return}places.forEach{(place)inputMarker(place:place)}return}print("error: \(error.localizedDescription)")}}// MARK: - GMSMapViewDelegateextensionViewController:GMSMapViewDelegate{}// MARK: - CLLocationManagerDelegateextensionViewController:CLLocationManagerDelegate{funclocationManager(_manager:CLLocationManager,didChangeAuthorizationstatus:CLAuthorizationStatus){switchstatus{case.notDetermined:breakcase.restricted,.denied:breakcase.authorizedWhenInUse:breakdefault:break}}funclocationManager(_manager:CLLocationManager,didUpdateLocationslocations:[CLLocation]){// 現在地の更新currentLocation=locations.last?.coordinateif!initView{// 初期描画時のマップ中心位置の移動letcamera=GMSCameraPosition.camera(withTarget:currentLocation!,zoom:zoomLevel)mapView.camera=camerainitView=true}}funclocationManager(_manager:CLLocationManager,didFailWithErrorerror:Error){if!CLLocationManager.locationServicesEnabled(){// 端末の位置情報がOFFになっている場合// アラートはデフォルトで表示されるので内部で用意はしないself.currentLocation=nilreturn}ifCLLocationManager.authorizationStatus()!=CLAuthorizationStatus.authorizedWhenInUse{// アプリの位置情報許可をOFFにしている場合return}}}
になります。
ポイントは、
ユーザアクション時に mainStore.dispatch メソッドを実行すること
これにより、どんなアクションが発生したのかを Reducer に伝え、 State を再生成することができるようになります。