Hi guys I’m building a fuse autocomplete module with foreign code and native integration of google place autocomplete.
the code is here https://github.com/princefr/Fuse.PlaceAutocomplete.
the android side works pretty well so I’m not gonna dwell on that ( to get the android part working you need to activate autocomplete for android in the google console and add the api key to geo.uxl file under com.google.android.geo.API_KEY).
this is the iOS part
using Uno;
using Uno.UX;
using Uno.Collections;
using Uno.Compiler.ExportTargetInterop;
using Fuse;
using Fuse.Triggers;
using Fuse.Controls;
using Fuse.Controls.Native;
using Fuse.Controls.Native.Android;
using Uno.Threading;
namespace Fuse.PlaceAutocomple
{
[Require("Cocoapods.Podfile.Target", "pod 'GooglePlaces'")]
[Require("Cocoapods.Podfile.Target", "pod 'GooglePlacePicker'")]
[Require("Cocoapods.Podfile.Target", "pod 'GoogleMaps'")]
[Require("Source.Include", "GooglePlaces/GooglePlaces.h")]
[Require("Source.Include", "GooglePlacePicker/GooglePlacePicker.h")]
[Require("Source.Include", "GoogleMaps/GoogleMaps.h")]
extern(iOS)
class Launch: Promise<string>
{
[Foreign(Language.ObjC)]
public Launch()
@{
[GMSPlacesClient provideAPIKey:@""];
[GMSServices provideAPIKey:@""];
GMSPlacePickerConfig *config = [[GMSPlacePickerConfig alloc] initWithViewport:nil];
GMSPlacePickerViewController *placePicker = [[GMSPlacePickerViewController alloc] initWithConfig:config];
dispatch_async(dispatch_get_main_queue(), ^{
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:placePicker animated:YES completion:nil];
});
@}
void Resolve(string message)
{
base.Resolve(message);
}
void Reject(string reason)
{
Reject(new Exception(reason));
}
}
}
to get it working you will need first to activate autocomplete for iOS in the google console and replace both [GMSPlacesClient provideAPIKey:@""] and [GMSServices provideAPIKey:@""] with an existing and functioning google apikey.
like its specified here https://developers.google.com/places/ios-api/placepicker?hl=fr. (ObjC part) we need to assign a placePicker.delegate to a controller view placePicker.delegate = self.
how can I achieve this using foreign code ?
second question I need to get the callback when user chooses a place and return it in my promise or when the user cancel the view and dismiss the place autocomplete view.
// To receive the results from the place picker 'self' will need to conform to
// GMSPlacePickerViewControllerDelegate and implement this code.
- (void)placePicker:(GMSPlacePickerViewController *)viewController didPickPlace:(GMSPlace *)place {
// Dismiss the place picker, as it cannot dismiss itself.
[viewController dismissViewControllerAnimated:YES completion:nil];
NSLog(@"Place name %@", place.name);
NSLog(@"Place address %@", place.formattedAddress);
NSLog(@"Place attributions %@", place.attributions.string);
}
- (void)placePickerDidCancel:(GMSPlacePickerViewController *)viewController {
// Dismiss the place picker, as it cannot dismiss itself.
[viewController dismissViewControllerAnimated:YES completion:nil];
NSLog(@"No place selected");
Did not find how to get it working with those links , can I have a more elaborate answer ?
this is what I’m doing now.
I tried to add a delegate by building an NSObject to get the autocomplete callback
this is the placeautocompleteIOS.h file
#import <placeautocompleteIOS.h>
#include <@{Fuse.PlaceAutocomple.PlaceAutocompleModule:Include}>
#include <@{ObjC.Object:Include}>
@implementation AutocompliteCallBacks : NSObject
// To receive the results from the place picker 'self' will need to conform to
// GMSPlacePickerViewControllerDelegate and implement this code.
- (void)placePicker:(GMSPlacePickerViewController *)viewController didPickPlace:(GMSPlace *)place {
NSLog(@"place name")
NSLog(@"Place name %@", place.name);
NSLog(@"Place address %@", place.formattedAddress);
NSLog(@"Place attributions %@", place.attributions.string);
}
- (void)placePickerDidCancel:(GMSPlacePickerViewController *)viewController {
NSLog(@"No place selected");
}
@end
then I pass my NSObject as delegate in my iOSimpl.uno as below
Hi updated my code and it seems to works properly but I have one last question about resolving and rejecting promise from foreign native file.
this is my placeautompleteiOS.mm file.
#pragma mark - GMSAutocompleteViewControllerDelegate
#include <Uno/Uno.h>
#include <@{Fuse.PlaceAutocomple.Launch:Include}>
#include <@{ObjC.Object:Include}>
#include "placeautocompleteIOS.h"
@interface AutocompliteCallBacks ()
@end
@implementation AutocompliteCallBacks
// To receive the results from the place picker 'self' will need to conform to
// GMSPlacePickerViewControllerDelegate and implement this code.
- (void)viewController:(GMSAutocompleteViewController *)viewController didAutocompleteWithPlace:(GMSPlace *)place {
// Do something with the selected place.
[[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:YES completion:nil];
NSLog(@"Place name %@", place.name);
NSLog(@"Place address %@", place.formattedAddress);
NSObject *object;
NSString *myString = place.formattedAddress;
@{Fuse.PlaceAutocomple.Launch.Resolve(string):Call(myString)};
}
- (void)viewController:(nonnull GMSAutocompleteViewController *)viewController didFailAutocompleteWithError:(nonnull NSError *)error {
[[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:YES completion:nil];
}
- (void)wasCancelled:(nonnull GMSAutocompleteViewController *)viewController {
[[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:YES completion:nil];
}
- (void)placePickerDidCancel:(GMSPlacePickerViewController *)viewController {
[[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:YES completion:nil];
//[self dismissViewControllerAnimated:YES completion:nil];
NSLog(@"No place selected");
}
@end