Community

Topic: Xamarin component

Google Map Events on iOS (SOLVED)

Bastian Buchholz
Monday, August 14, 2017

Hello,
We are using the PKTGeoMainController on iOS
In our app we want to listen to the CameraChange event of Google Maps to load new data from the server.
On Android we found a way to get to the Google Map object via FragmentManager.FindFragmentById(Resource.Id.fragment_pikkart_geo_layout).GetMapAsync(...).
Is something like this also possible on iOS? If not would it be possible to expose the Google Map events / delegates on the PKTGeoMainController ?
Regards

user profile image
Support Team  (expert)
Wednesday, August 16, 2017

Hello,
yes it is possible to retrieve google Map delegate instance variable and Google Maps instance variable using Objective C KVO feature, inside PKTGeoMainController subclass:

id mapDelegate = [self valueForKey:@"googlemap"];

GMSMapView * mapView=[[self valueForKey:@"googlemap"] valueForKey:@"mapView"];

You could set a new map delegate as follow:
[self setValue:YourMapViewDelegateSubClass forKey:@"googlemap"];

Be careful to use this approach, because some of the delegate methods are used inside Pikkart Geo SDK
(for example, - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker).
Then, you should try to use only notifications events associated on GMSMapView (change frame, alpha or some other observable properties),
but change its delegate object is not recommended.
Best,

Bastian Buchholz
Friday, August 18, 2017

Thanks for the answer. But sadly with Xamarin this does not work because of the missing Google Maps C# bindings.
If I add the Xamarin.Google.iOS.Maps NuGet package then the bindings are there but it looks like Pikkart and Xamarin.Google.iOS.Maps do not work together.
I get the following compile error:

1>  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang  -framework UIKit -framework Foundation -framework CoreLocation -framework QuartzCore -framework CoreGraphics -framework CloudKit -framework Accelerate -framework GLKit -framework ImageIO -framework OpenGLES -framework CoreText -framework Security -framework CoreData -framework SystemConfiguration -weak_framework CFNetwork /obj/iPhone/Debug/mtouch-cache/armv7/registrar.o /obj/iPhone/Debug/mtouch-cache/armv7/main.o /obj/iPhone/Debug/mtouch-cache/armv7/PikkartGoogleMaps.exe.o /obj/iPhone/Debug/mtouch-cache/armv7/mscorlib.dll.o /obj/iPhone/Debug/mtouch-cache/armv7/Xamarin.iOS.dll.o /obj/iPhone/Debug/mtouch-cache/armv7/Google.Maps.dll.o /obj/iPhone/Debug/mtouch-cache/armv7/Pikkart.ArSdk.Geo.dll.o /obj/iPhone/Debug/mtouch-cache/GoogleMaps /obj/iPhone/Debug/mtouch-cache/GoogleMapsCore /obj/iPhone/Debug/mtouch-cache/GoogleMapsBase /obj/iPhone/Debug/mtouch-cache/GooglePlaces /obj/iPhone/Debug/mtouch-cache/GooglePlacePicker /obj/iPhone/Debug/mtouch-cache/pikkartARGeo /Library/Frameworks/Xamarin.iOS.framework/Versions/10.12.0.18/SDKs/MonoTouch.iphoneos.sdk/usr/lib/libmonosgen-2.0.a /Library/Frameworks/Xamarin.iOS.framework/Versions/10.12.0.18/SDKs/MonoTouch.iphoneos.sdk/usr/lib/libxamarin-debug.a -force_load /Library/Frameworks/Xamarin.iOS.framework/Versions/10.12.0.18/SDKs/MonoTouch.iphoneos.sdk/usr/lib/libapp.a -ObjC -ObjC -lz -lc++ -Wl,-pie -arch armv7 -miphoneos-version-min=10.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk -lz -liconv -o /obj/iPhone/Debug/mtouch-cache/32/Output/PikkartGoogleMaps -u _UIApplicationMain -u _xamarin_get_block_descriptor -u _kGMSAccessibilityCompass -u _kGMSAccessibilityMyLocation -u _kGMSAutocompleteMatchAttribute -u _kGMSEquatorProjectedMeter -u _kGMSLayerCameraBearingKey -u _kGMSLayerCameraLatitudeKey -u _kGMSLayerCameraLongitudeKey -u _kGMSLayerCameraViewingAngleKey -u _kGMSLayerCameraZoomLevelKey -u _kGMSLayerPanoramaFOVKey -u _kGMSLayerPanoramaHeadingKey -u _kGMSLayerPanoramaPitchKey -u _kGMSLayerPanoramaZoomKey -u _kGMSMarkerLayerLatitude -u _kGMSMarkerLayerLongitude -u _kGMSMarkerLayerRotation -u _kGMSMaxZoomLevel -u _kGMSMinZoomLevel -u _kGMSPlacePickerErrorDomain -u _kGMSPlacesErrorDomain -u _kGMSGroundOverlayDefaultAnchor -u _kGMSMarkerDefaultGroundAnchor -u _kGMSMarkerDefaultInfoWindowAnchor -u _kGMSTileLayerNoTile -u _mono_pmip

1> ld: framework not found GoogleMaps for architecture armv7
1> clang: error: linker command failed with exit code 1 (use -v to see invocation)
If I remove Pikkart it compiles again.
I have also created a demo project which reproduces the problem: https://github.com/campersau/pikkart-googlemaps-xamarin
Since the original Xamarin.Google.iOS.Maps version is a little older I have also create a newer package but this does not help.
Any ideas why this error is happening?
Regards

user profile image
Support Team  (expert)
Friday, August 18, 2017

Hello,
yes, you are right.
Unfortunately , the Xamarin Google Maps nuget is not aligned with Pikkart SDK requirements: Pikkart SDK requires Google Maps 2.2.0 or greater, but Xamarin Google Maps nuget is still aligned to 2.1.0 version...
What you should do, in order to use Google Maps binding library, is:

  1. Remove Xamarin Google Maps nuget
  2. Download last Xamarin Google Maps binding library from this link and add project to your solution: https://github.com/mono/monotouch-bindings/tree/master/GoogleMaps
  3. Update Google Maps Native reference library with last Google Maps iOS SDK
  4. Ubviously, add "using Google.Maps" directive where you retrieve MapView binding Object

If you are using our Pikkart Geo tutorial, check Options -> iOS Build -> mtouch Additional arguments
and remove Google Maps -framework directive
Regards

Bastian Buchholz
Sunday, August 20, 2017

Thanks!
I got it working now. I had to add the additional MtouchExtraArgs without the GoogleMaps framework.
So this is what I have done:

  • Xamarin.Google.iOS.Maps 2.4.0 (https://github.com/campersau/GoogleApisForiOSComponents/tree/vnext)
  • Newest Google Maps Native Reference (only copied to output folder)
  • MtouchExtraArgs without GoogleMaps framework
  • Pikkart

  • I have overriden den Delegate and keep a reference to the original one.
    It looks like Pikkart only implements these two methods:
    [Export("mapView:didTapAtCoordinate:")]
    
    public void DidTapAtCoordinate(MapView mapView, CLLocationCoordinate2D coordinate)
    {
    _innerMapViewDelegate.DidTapAtCoordinate(mapView, coordinate); // this will call OnMapOrCameraClicked
    }

    [Export("mapView:didTapMarker:")]
    public bool TappedMarker(MapView mapView, Marker marker)
    {
    return _innerMapViewDelegate.TappedMarker(mapView, marker); // this will call GeoElementClicked
    }

Sign in to add a comment