0
votes

I am building my first objective c library binding. I am following this documentation from Microsoft. I have successfully created a fat binary from IronSource.framework and have also generated apidefinition and structs using objective sharpie and added my binary to it.

After doing that I added binding library to my xamarin.ios project. when i try to create a new instance of a class from the exposed API I get an error.

The type or namespace name 'IronSource' could not be found (are you missing a using directive or an assembly reference?) Stock.iOS D:\Backup Version for Stock Adviser\Version 1.6\Version code 37\StockAdviserCode\Stock\Stock\Stock.iOS\AdControlViewRenderer.cs

'AdControlViewRenderer.BannerWrapper' does not implement inherited abstract member 'ISBannerDelegate.DidClickBanner()' Stock.iOS D:\Backup Version for Stock Adviser\Version 1.6\Version code 37\StockAdviserCode\Stock\Stock\Stock.iOS\AdControlViewRenderer.cs

I think my objective c library and xamarin.ios project are not linking properly

My Binding project name is IronSource and my xamarin forms ios project name is Stock.iOS

//APIDefinition
    using System;
    using Foundation;
    using ObjCRuntime;
    using UIKit;

namespace IronSource
{

    // @interface ISBannerView : UIView
    [BaseType(typeof(UIView))]
    interface ISBannerView
    {
    }

    // @protocol ISBannerDelegate <NSObject>
    [BaseType(typeof(NSObject))]
    [Model]
    interface ISBannerDelegate
    {
        // @required -(void)bannerDidLoad:(ISBannerView *)bannerView;
        [Abstract]
        [Export("bannerDidLoad:")]
        void BannerDidLoad(ISBannerView bannerView);

        // @required -(void)bannerDidFailToLoadWithError:(NSError *)error;
        [Abstract]
        [Export("bannerDidFailToLoadWithError:")]
        void BannerDidFailToLoadWithError(NSError error);

        // @required -(void)didClickBanner;
        [Abstract]
        [Export("didClickBanner")]
        void DidClickBanner();

        // @required -(void)bannerWillPresentScreen;
        [Abstract]
        [Export("bannerWillPresentScreen")]
        void BannerWillPresentScreen();

        // @required -(void)bannerDidDismissScreen;
        [Abstract]
        [Export("bannerDidDismissScreen")]
        void BannerDidDismissScreen();

        // @required -(void)bannerWillLeaveApplication;
        [Abstract]
        [Export("bannerWillLeaveApplication")]
        void BannerWillLeaveApplication();
    }
}

//my xamarin.ios

using System;
using CoreGraphics;
using Foundation;
using Stock.iOS;
using Stock.Services;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using IronSource;

[assembly: ExportRenderer(typeof(AdControlView), typeof(AdControlViewRenderer))]
namespace Stock.iOS
{

public class AdControlViewRenderer : ViewRenderer
{
    public AdControlViewRenderer()
    { }
    protected AdControlView AdViewControl => (AdControlView)Element;
    protected override void OnElementChanged(ElementChangedEventArgs<View> e)
    {
        base.OnElementChanged(e);
        if (e.OldElement != null || Element == null)
            return;

        IronSource ironSource = new IronSource();

        SetNativeControl();
    }

    private void SetNativeControl()
    {
        try
        {
            BannerWrapper bannerWrapper = new BannerWrapper(ViewController);

            IronSource.SetBannerDelegate(bannerWrapper);

            var bannerSize = new ISBannerSize("BANNER");
            IronSource.LoadBannerWithViewController(ViewController, bannerSize);
            var adview = bannerWrapper.BannerView();
            SetNativeControl(adview);
        }
        catch (Exception ex)
        {

        }
    }
}

public class BannerWrapper : ISBannerDelegate
{
    readonly UIViewController parent;
    ISBannerView bannerView = null;

    public bool DestroyBanner()
    {
        if (bannerView != null)
        {
            IronSource.DestroyBanner(bannerView);
            bannerView = null;
            return true;
        }
        return false;
    }

    public BannerWrapper(UIViewController viewController)
    {
        this.parent = viewController;
    }
    public override void BannerDidClick()
    {
    }

    public override void BannerDidDismissScreen()
    {
    }

    public override void BannerDidFailToLoadWithError(NSError error)
    {
    }

    public ISBannerView BannerView()
    {
        ISBannerView bannerView = new ISBannerView();
        nfloat y = this.parent.View.Frame.Size.Height - (bannerView.Frame.Size.Height / 2);
        if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
        {
            y -= this.parent.View.SafeAreaInsets.Bottom;
        }
        bannerView.Center = new CGPoint(this.parent.View.Frame.Size.Width / 2, y);

        return bannerView;
    }

    public override void BannerDidLoad(ISBannerView bnView)
    {
        InvokeOnMainThread(() =>
        {

            bannerView = bnView;

            nfloat y = this.parent.View.Frame.Size.Height - (bannerView.Frame.Size.Height / 2);
            if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
            {
                y -= this.parent.View.SafeAreaInsets.Bottom;
            }
            bannerView.Center = new CGPoint(this.parent.View.Frame.Size.Width / 2, y);

            this.parent.View.AddSubview(bannerView);

            bannerView.AccessibilityLabel = "bannerContainer";

        });

    }

    public override void BannerWillLeaveApplication()
    {
    }

    public override void BannerWillPresentScreen()
    {
    }
}
}

Any help is welcome

1
Hi , when adding library to xamarin ios , could you see the linkwith.cs file in your project ?Junior Jiang
yes I am able to see linkwith.cs in binding projectA for android
Okey , then could you see [assembly: LinkWith ("xxx.a", SmartLink = true, ForceLoad = true)] code inside linkwith.cs? That's used to invoke library .Junior Jiang

1 Answers

0
votes

So, I was able to make it work by adding fat binary to Xamarin.ios and changed the build type from "Do not copy" to "Copy Always" and then added a linker to that fat binary using -cxx -gcc_flags "-L${ProjectDir} -lIronSource -force_load ${ProjectDir}/IronSource.a

I used this GitHub repo for guidance.

Overall to setup IronSoruce, I had to add dll in references, native framework to native reference, fat binary to projectdir and add linker to fat binary.