# need help with foreign code on iOS.

**URL:** <https://forums.fusetools.com/t/need-help-with-foreign-code-on-ios/6702>\
**Category:** How-to Discussions\
**Created:** [March 20, 2018, 9:04am UTC](https://forums.fusetools.com/t/need-help-with-foreign-code-on-ios/6702 "2018-03-20T09:04:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![prince](https://avatars.discourse-cdn.com/v4/letter/p/ba9def/32.png) [@prince](https://forums.fusetools.com/u/prince)\
**Post date:** [March 20, 2018, 9:04am UTC](https://forums.fusetools.com/t/need-help-with-foreign-code-on-ios/6702/1 "2018-03-20T09:04:08Z")

</div>

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](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

```auto
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](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.

```auto
// 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");

```

how can I achieve this in foreign code ?

---

<div class="post-metadata">

**Author:** ![Uldis](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/uldis/32/657_2.png) [@Uldis](https://forums.fusetools.com/u/Uldis)\
**Post date:** [March 21, 2018, 7:37am UTC](https://forums.fusetools.com/t/need-help-with-foreign-code-on-ios/6702/2 "2018-03-21T07:37:00Z")

</div>

I have a hunch that [Fuse.Share](https://github.com/fusetools/fuselibs-public/tree/master/Source/Fuse.Share) implementation might hold some good tips. Or perhaps the [DatePicker](https://github.com/fusetools/fuselibs-public/tree/master/Source/Fuse.Controls.DatePicker).

---

<div class="post-metadata">

**Author:** ![prince](https://avatars.discourse-cdn.com/v4/letter/p/ba9def/32.png) [@prince](https://forums.fusetools.com/u/prince)\
**Post date:** [March 22, 2018, 9:32am UTC](https://forums.fusetools.com/t/need-help-with-foreign-code-on-ios/6702/3 "2018-03-22T09:32:28Z")

</div>

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

```auto
#include <GoogleMaps/GoogleMaps.h>
#include <GooglePlacePicker/GooglePlacePicker.h>
#include <GooglePlaces/GooglePlaces.h>

@interface AutocompliteCallBacks : NSObject<GMSPlacePickerViewControllerDelegate>

@end

```

and this is the placeautompleteiOS.mm file

```auto

#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

`placePicker.delegate = [[AutocompliteCallBacks alloc] init];`

but still not working.

any tips ?

---

<div class="post-metadata">

**Author:** ![prince](https://avatars.discourse-cdn.com/v4/letter/p/ba9def/32.png) [@prince](https://forums.fusetools.com/u/prince)\
**Post date:** [March 24, 2018, 5:57am UTC](https://forums.fusetools.com/t/need-help-with-foreign-code-on-ios/6702/4 "2018-03-24T05:57:25Z")

</div>

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.

```auto
#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

```

this is my placeautocompleteIOS file

```auto
#include <UIKit/UIKit.h>
#include <Uno-iOS/Context.h>
#include <Uno-iOS/Uno-iOS.h>
#include <GoogleMaps/GoogleMaps.h>
#include <GooglePlacePicker/GooglePlacePicker.h>
#include <GooglePlaces/GooglePlaces.h>

@interface AutocompliteCallBacks : NSObject <GMSAutocompleteViewControllerDelegate>
- (void)viewController:(GMSAutocompleteViewController *)viewController didAutocompleteWithPlace:(GMSPlace *)place;
- (void)placePickerDidCancel:(GMSPlacePickerViewController *)viewController;
- (void)viewController:(nonnull GMSAutocompleteViewController *)viewController didFailAutocompleteWithError:(nonnull NSError *)error;
- (void)wasCancelled:(nonnull GMSAutocompleteViewController *)viewController;
@end

```

and the last one file my iOSimpl.uno file

```auto
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")]
    [Require("Source.Include", "placeautocompleteIOS.h")]
    [Require("Entity", "Fuse.PlaceAutocomple.Launch.Resolve(string)")]
  extern(iOS)
   class Launch: Promise<string>
  {

  	extern(iOS) static internal ObjC.Object _iosDelegate;

    [Foreign(Language.ObjC)]
    public Launch()
    @{

    	  [GMSPlacesClient provideAPIKey:@"APIKEY"];
    	  [GMSServices provideAPIKey:@"APIKEY"];

        	dispatch_async(dispatch_get_main_queue(), ^{
        		GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init];
        		AutocompliteCallBacks *del = [[AutocompliteCallBacks alloc] init];
            	@{_iosDelegate:Set(del)};
            	acController.delegate = @{_iosDelegate:Get()};
				[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:acController animated:YES completion:nil];
			});

    @}

    void Resolve(string message)
      {
        base.Resolve(message);
      }

      void Reject(string reason)
      {
        Reject(new Exception(reason));
      }

  }

}

```

how can I resolve or reject my Launch uno promise from my placeautompleteiOS.mm file
