How to reference class from iOS project to the main project in xamarin











up vote
0
down vote

favorite












I'm creating an app in which, the login will be handled using auth0. But due to the available Auth0 NuGet packages, I had to create separate login pages for android and iOS. So in the app.xaml.cs class, I now have to reference Login_iOS for case Device.iOS: MainPage = new Login_iOS⁩(); but I am met with an error, as xamarin cannot find the class Login_iOS. I'm pretty sure that this is because I haven't referenced it correctly, and I can't seem to find a way to reference it correctly. The screenshots below should help me explain my situation.



App.xaml.csLogin_iOS










share|improve this question






















  • like I suggested on your previous question, consider using a Custom Renderer
    – Jason
    Nov 22 at 1:57















up vote
0
down vote

favorite












I'm creating an app in which, the login will be handled using auth0. But due to the available Auth0 NuGet packages, I had to create separate login pages for android and iOS. So in the app.xaml.cs class, I now have to reference Login_iOS for case Device.iOS: MainPage = new Login_iOS⁩(); but I am met with an error, as xamarin cannot find the class Login_iOS. I'm pretty sure that this is because I haven't referenced it correctly, and I can't seem to find a way to reference it correctly. The screenshots below should help me explain my situation.



App.xaml.csLogin_iOS










share|improve this question






















  • like I suggested on your previous question, consider using a Custom Renderer
    – Jason
    Nov 22 at 1:57













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm creating an app in which, the login will be handled using auth0. But due to the available Auth0 NuGet packages, I had to create separate login pages for android and iOS. So in the app.xaml.cs class, I now have to reference Login_iOS for case Device.iOS: MainPage = new Login_iOS⁩(); but I am met with an error, as xamarin cannot find the class Login_iOS. I'm pretty sure that this is because I haven't referenced it correctly, and I can't seem to find a way to reference it correctly. The screenshots below should help me explain my situation.



App.xaml.csLogin_iOS










share|improve this question













I'm creating an app in which, the login will be handled using auth0. But due to the available Auth0 NuGet packages, I had to create separate login pages for android and iOS. So in the app.xaml.cs class, I now have to reference Login_iOS for case Device.iOS: MainPage = new Login_iOS⁩(); but I am met with an error, as xamarin cannot find the class Login_iOS. I'm pretty sure that this is because I haven't referenced it correctly, and I can't seem to find a way to reference it correctly. The screenshots below should help me explain my situation.



App.xaml.csLogin_iOS







c# xamarin xamarin.forms xamarin.ios auth0






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 at 22:31









Mohamed Al Sabbagh

144




144












  • like I suggested on your previous question, consider using a Custom Renderer
    – Jason
    Nov 22 at 1:57


















  • like I suggested on your previous question, consider using a Custom Renderer
    – Jason
    Nov 22 at 1:57
















like I suggested on your previous question, consider using a Custom Renderer
– Jason
Nov 22 at 1:57




like I suggested on your previous question, consider using a Custom Renderer
– Jason
Nov 22 at 1:57












2 Answers
2






active

oldest

votes

















up vote
0
down vote



accepted










Using an IoC (Inversion of Control) is one way to go as pointed out by Shawn, but understand that IoC is a name for one method of calling into platform specific code from a platform agnostic library project like a .NET Standard project. You have to decide on what IoC library to use, or whether to use IoC functionality that is built into some cross-platform frameworks like MvvmCross or even Xamarin.Forms Dependency Service (which is not a true IoC container but more of a service locator, but it does work to allow you to call platform specific code from a .NET Standard or PCL library project, which is ultimately what you want to do).



That said, there is another option for your core Xamarin.Forms code and that is to use a Shared Library project type. .NET Standard is by far the more common and the option that is suggested when you follow the getting started docs for Xamarin.Forms (and Xamarin.Forms != Xamarin see (1) below) You can select this when you create your Xamarin.Forms solution:



enter image description here



With a Shared library project type for your core Xamarin.Forms code, you will have access to everything that is referenced in your platform specific projects so you will access to everything that you have access to in the Xamarin.iOS and Xamarin.Android projects directly. No IoC or Dependency services are necessary.



There has always been much debate on whether using a Shared Library project or a .NET Standard project is the best way to go. There are pros and cons to each. In a nutshell using a .NET Standard project forces you to use IoC to call platform specific code from the library project, and use custom renderers to access platform specific properties of UI controls, whereas a Shared Library project give you full access to all the classes and libraries that are available to the platform specific project, making Dependency Injection unnecessary... BUT when using a Shared project, since you can have both Xamarin.Android specific and Xamarin.iOS specific code in the same Shared project, you need to use compiler directives (#if and #endif) so that iOS specific code is only compiled when building the iOS project and Android specific code is only compiled when compiling the Android project. Not doing so can cause compile and/or runtime issues. Here is a simple piece of code to show you how to use the compiler directives to isolate iOS and Android specific code. This simple sample will create a button that when tapped will present an Alert. How to present an Alert is different between iOS and Android so we need to isolate those bits of code in the button click event handler so the correct code runs on the correct platform.



First define the compiler symbols in the Project Options. Right click on the Android project and select Project Options and select Compiler on the left. Then in the Define Symbols field, add ANDROID;, e.g.:



enter image description here



Then do the same for the iOS project (but entering IOS obviously):



enter image description here



It is worth noting that this is a configuration dependent setting, so you need to add these symbols for all of the configurations that you will use to build your projects.



Next create the button in MainPage.xaml:



<Button Text="Show me an alert!" 
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Clicked="Handle_Clicked" />


Then in the MainPage.xaml.cs code behind file:



    void Handle_Clicked(object sender, System.EventArgs e)
{
#if ANDROID
Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
#endif
#if IOS
var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
alert.Show();
#endif
}


You will also need the compiler directives around the using statements:



#if ANDROID
using Android.Widget;
using SharedSample.Droid;
#endif
#if IOS
using UIKit;
#endif


So hopefully now you better understand how to make cross platform apps and some of the challenges around sharing code and using platform specific code. All that said, you still will not be able to add a native iOS page (or native Android page) to your Xamarin.Forms MainPage property since the iOS page is NOT a Xamarin.Form page (MainPage can only accept a subclass of a Xamarin.Forms Page), but this should show you how to call platform specific code from your shared code.



Oh, now I see in your screenshots that you added your Xamarin.Forms XAML page to the iOS project???? No, that is not the way around your issue. I would seriously suggest you sign up for Xamarin University. You need more than just code snippets, you need to better understand cross-platform development and my not-so-brief primer here is not nearly enough to get you going from what I can see.



BUt you know what, I think there is a OAuth library for Xamarin Forms, so maybe you can make that work as it should do all the platform specific stuff for you.
Nuget page: https://www.nuget.org/packages/Xamarin.Auth/
Github page: https://github.com/xamarin/Xamarin.Auth
Docs: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth



Good luck!



(1) Xamarin was a company that was purchased by Microsoft. Xamarin made SDKs that allowed making apps for iOS, Mac, and Android using C# and the .NET framework. Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono which is an open source port of .NET (since .NET only ran on Windows and other Microsoft platforms at the time... though there is now .NET Core that is cross-platform... but that is another topic).
Later Xamarin introduced Xamarin.Forms which is a cross-platform UI (User Interface) library that allows creating the UI in common code and/or XAML. Prior to Xamarin.Forms, the UI for each platform had to be created in the platform specific projects, i.e. the UI for iOS would be in Xamarin.iOS project, UI for Android would be in Xamarin.Android project, etc., but all could call into back end code (i.e. web requests, models, etc.) that resides in one shared library project, allowing about 80% of the total code to be shared between the different platform app projects. With Xamarin.Forms, for a simple app, 100% code sharing is possible. Xamarin.Forms does still use Xamarin.iOS and Xamarin.Android projects, as well as UWP projects on Windows, to kick off the UI, but Xamarin.Forms uses renderers to render the Xamarin.Forms UI Controls into platform specific controls, i.e. a Button in Xam.Forms renders to a UIButton on iOS and an Android Button on Android. However Xamarin.Forms only gives you access to core common properties of the native controls, so if you need to access specific native properties or features, you have to use a custom renderer (to modify UI controls on the native platform and have access to native control's properties) and/or dependency service (to run platform specific code from the core Xam.Forms library project).






share|improve this answer




























    up vote
    0
    down vote













    Your base project cannot reference the platform specific project. If you could do that, you would be back in the boat of using platform specific libraries on the wrong platform.



    Instead, you need to create a class or interface in your base project that each of your platform specific projects can extend. This way, you can pass that base class between projects without needing to know about any of the platform specific libraries that are being used.



    I would recommend an IoC (Inversion of Control) pattern for this situation. It abstracts the reference handling for you and simplifies the registration of your various services. Take a look at this article which is solving the exact same type of situation.



    I hope this helps!






    share|improve this answer





















    • Sorry, still not sure how IoC's should be implemented to help in my situation. If you could please explain it that would be great!
      – Mohamed Al Sabbagh
      Nov 21 at 23:09











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421353%2fhow-to-reference-class-from-ios-project-to-the-main-project-in-xamarin%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    Using an IoC (Inversion of Control) is one way to go as pointed out by Shawn, but understand that IoC is a name for one method of calling into platform specific code from a platform agnostic library project like a .NET Standard project. You have to decide on what IoC library to use, or whether to use IoC functionality that is built into some cross-platform frameworks like MvvmCross or even Xamarin.Forms Dependency Service (which is not a true IoC container but more of a service locator, but it does work to allow you to call platform specific code from a .NET Standard or PCL library project, which is ultimately what you want to do).



    That said, there is another option for your core Xamarin.Forms code and that is to use a Shared Library project type. .NET Standard is by far the more common and the option that is suggested when you follow the getting started docs for Xamarin.Forms (and Xamarin.Forms != Xamarin see (1) below) You can select this when you create your Xamarin.Forms solution:



    enter image description here



    With a Shared library project type for your core Xamarin.Forms code, you will have access to everything that is referenced in your platform specific projects so you will access to everything that you have access to in the Xamarin.iOS and Xamarin.Android projects directly. No IoC or Dependency services are necessary.



    There has always been much debate on whether using a Shared Library project or a .NET Standard project is the best way to go. There are pros and cons to each. In a nutshell using a .NET Standard project forces you to use IoC to call platform specific code from the library project, and use custom renderers to access platform specific properties of UI controls, whereas a Shared Library project give you full access to all the classes and libraries that are available to the platform specific project, making Dependency Injection unnecessary... BUT when using a Shared project, since you can have both Xamarin.Android specific and Xamarin.iOS specific code in the same Shared project, you need to use compiler directives (#if and #endif) so that iOS specific code is only compiled when building the iOS project and Android specific code is only compiled when compiling the Android project. Not doing so can cause compile and/or runtime issues. Here is a simple piece of code to show you how to use the compiler directives to isolate iOS and Android specific code. This simple sample will create a button that when tapped will present an Alert. How to present an Alert is different between iOS and Android so we need to isolate those bits of code in the button click event handler so the correct code runs on the correct platform.



    First define the compiler symbols in the Project Options. Right click on the Android project and select Project Options and select Compiler on the left. Then in the Define Symbols field, add ANDROID;, e.g.:



    enter image description here



    Then do the same for the iOS project (but entering IOS obviously):



    enter image description here



    It is worth noting that this is a configuration dependent setting, so you need to add these symbols for all of the configurations that you will use to build your projects.



    Next create the button in MainPage.xaml:



    <Button Text="Show me an alert!" 
    HorizontalOptions="Center"
    VerticalOptions="CenterAndExpand"
    Clicked="Handle_Clicked" />


    Then in the MainPage.xaml.cs code behind file:



        void Handle_Clicked(object sender, System.EventArgs e)
    {
    #if ANDROID
    Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
    #endif
    #if IOS
    var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
    alert.Show();
    #endif
    }


    You will also need the compiler directives around the using statements:



    #if ANDROID
    using Android.Widget;
    using SharedSample.Droid;
    #endif
    #if IOS
    using UIKit;
    #endif


    So hopefully now you better understand how to make cross platform apps and some of the challenges around sharing code and using platform specific code. All that said, you still will not be able to add a native iOS page (or native Android page) to your Xamarin.Forms MainPage property since the iOS page is NOT a Xamarin.Form page (MainPage can only accept a subclass of a Xamarin.Forms Page), but this should show you how to call platform specific code from your shared code.



    Oh, now I see in your screenshots that you added your Xamarin.Forms XAML page to the iOS project???? No, that is not the way around your issue. I would seriously suggest you sign up for Xamarin University. You need more than just code snippets, you need to better understand cross-platform development and my not-so-brief primer here is not nearly enough to get you going from what I can see.



    BUt you know what, I think there is a OAuth library for Xamarin Forms, so maybe you can make that work as it should do all the platform specific stuff for you.
    Nuget page: https://www.nuget.org/packages/Xamarin.Auth/
    Github page: https://github.com/xamarin/Xamarin.Auth
    Docs: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth



    Good luck!



    (1) Xamarin was a company that was purchased by Microsoft. Xamarin made SDKs that allowed making apps for iOS, Mac, and Android using C# and the .NET framework. Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono which is an open source port of .NET (since .NET only ran on Windows and other Microsoft platforms at the time... though there is now .NET Core that is cross-platform... but that is another topic).
    Later Xamarin introduced Xamarin.Forms which is a cross-platform UI (User Interface) library that allows creating the UI in common code and/or XAML. Prior to Xamarin.Forms, the UI for each platform had to be created in the platform specific projects, i.e. the UI for iOS would be in Xamarin.iOS project, UI for Android would be in Xamarin.Android project, etc., but all could call into back end code (i.e. web requests, models, etc.) that resides in one shared library project, allowing about 80% of the total code to be shared between the different platform app projects. With Xamarin.Forms, for a simple app, 100% code sharing is possible. Xamarin.Forms does still use Xamarin.iOS and Xamarin.Android projects, as well as UWP projects on Windows, to kick off the UI, but Xamarin.Forms uses renderers to render the Xamarin.Forms UI Controls into platform specific controls, i.e. a Button in Xam.Forms renders to a UIButton on iOS and an Android Button on Android. However Xamarin.Forms only gives you access to core common properties of the native controls, so if you need to access specific native properties or features, you have to use a custom renderer (to modify UI controls on the native platform and have access to native control's properties) and/or dependency service (to run platform specific code from the core Xam.Forms library project).






    share|improve this answer

























      up vote
      0
      down vote



      accepted










      Using an IoC (Inversion of Control) is one way to go as pointed out by Shawn, but understand that IoC is a name for one method of calling into platform specific code from a platform agnostic library project like a .NET Standard project. You have to decide on what IoC library to use, or whether to use IoC functionality that is built into some cross-platform frameworks like MvvmCross or even Xamarin.Forms Dependency Service (which is not a true IoC container but more of a service locator, but it does work to allow you to call platform specific code from a .NET Standard or PCL library project, which is ultimately what you want to do).



      That said, there is another option for your core Xamarin.Forms code and that is to use a Shared Library project type. .NET Standard is by far the more common and the option that is suggested when you follow the getting started docs for Xamarin.Forms (and Xamarin.Forms != Xamarin see (1) below) You can select this when you create your Xamarin.Forms solution:



      enter image description here



      With a Shared library project type for your core Xamarin.Forms code, you will have access to everything that is referenced in your platform specific projects so you will access to everything that you have access to in the Xamarin.iOS and Xamarin.Android projects directly. No IoC or Dependency services are necessary.



      There has always been much debate on whether using a Shared Library project or a .NET Standard project is the best way to go. There are pros and cons to each. In a nutshell using a .NET Standard project forces you to use IoC to call platform specific code from the library project, and use custom renderers to access platform specific properties of UI controls, whereas a Shared Library project give you full access to all the classes and libraries that are available to the platform specific project, making Dependency Injection unnecessary... BUT when using a Shared project, since you can have both Xamarin.Android specific and Xamarin.iOS specific code in the same Shared project, you need to use compiler directives (#if and #endif) so that iOS specific code is only compiled when building the iOS project and Android specific code is only compiled when compiling the Android project. Not doing so can cause compile and/or runtime issues. Here is a simple piece of code to show you how to use the compiler directives to isolate iOS and Android specific code. This simple sample will create a button that when tapped will present an Alert. How to present an Alert is different between iOS and Android so we need to isolate those bits of code in the button click event handler so the correct code runs on the correct platform.



      First define the compiler symbols in the Project Options. Right click on the Android project and select Project Options and select Compiler on the left. Then in the Define Symbols field, add ANDROID;, e.g.:



      enter image description here



      Then do the same for the iOS project (but entering IOS obviously):



      enter image description here



      It is worth noting that this is a configuration dependent setting, so you need to add these symbols for all of the configurations that you will use to build your projects.



      Next create the button in MainPage.xaml:



      <Button Text="Show me an alert!" 
      HorizontalOptions="Center"
      VerticalOptions="CenterAndExpand"
      Clicked="Handle_Clicked" />


      Then in the MainPage.xaml.cs code behind file:



          void Handle_Clicked(object sender, System.EventArgs e)
      {
      #if ANDROID
      Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
      #endif
      #if IOS
      var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
      alert.Show();
      #endif
      }


      You will also need the compiler directives around the using statements:



      #if ANDROID
      using Android.Widget;
      using SharedSample.Droid;
      #endif
      #if IOS
      using UIKit;
      #endif


      So hopefully now you better understand how to make cross platform apps and some of the challenges around sharing code and using platform specific code. All that said, you still will not be able to add a native iOS page (or native Android page) to your Xamarin.Forms MainPage property since the iOS page is NOT a Xamarin.Form page (MainPage can only accept a subclass of a Xamarin.Forms Page), but this should show you how to call platform specific code from your shared code.



      Oh, now I see in your screenshots that you added your Xamarin.Forms XAML page to the iOS project???? No, that is not the way around your issue. I would seriously suggest you sign up for Xamarin University. You need more than just code snippets, you need to better understand cross-platform development and my not-so-brief primer here is not nearly enough to get you going from what I can see.



      BUt you know what, I think there is a OAuth library for Xamarin Forms, so maybe you can make that work as it should do all the platform specific stuff for you.
      Nuget page: https://www.nuget.org/packages/Xamarin.Auth/
      Github page: https://github.com/xamarin/Xamarin.Auth
      Docs: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth



      Good luck!



      (1) Xamarin was a company that was purchased by Microsoft. Xamarin made SDKs that allowed making apps for iOS, Mac, and Android using C# and the .NET framework. Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono which is an open source port of .NET (since .NET only ran on Windows and other Microsoft platforms at the time... though there is now .NET Core that is cross-platform... but that is another topic).
      Later Xamarin introduced Xamarin.Forms which is a cross-platform UI (User Interface) library that allows creating the UI in common code and/or XAML. Prior to Xamarin.Forms, the UI for each platform had to be created in the platform specific projects, i.e. the UI for iOS would be in Xamarin.iOS project, UI for Android would be in Xamarin.Android project, etc., but all could call into back end code (i.e. web requests, models, etc.) that resides in one shared library project, allowing about 80% of the total code to be shared between the different platform app projects. With Xamarin.Forms, for a simple app, 100% code sharing is possible. Xamarin.Forms does still use Xamarin.iOS and Xamarin.Android projects, as well as UWP projects on Windows, to kick off the UI, but Xamarin.Forms uses renderers to render the Xamarin.Forms UI Controls into platform specific controls, i.e. a Button in Xam.Forms renders to a UIButton on iOS and an Android Button on Android. However Xamarin.Forms only gives you access to core common properties of the native controls, so if you need to access specific native properties or features, you have to use a custom renderer (to modify UI controls on the native platform and have access to native control's properties) and/or dependency service (to run platform specific code from the core Xam.Forms library project).






      share|improve this answer























        up vote
        0
        down vote



        accepted







        up vote
        0
        down vote



        accepted






        Using an IoC (Inversion of Control) is one way to go as pointed out by Shawn, but understand that IoC is a name for one method of calling into platform specific code from a platform agnostic library project like a .NET Standard project. You have to decide on what IoC library to use, or whether to use IoC functionality that is built into some cross-platform frameworks like MvvmCross or even Xamarin.Forms Dependency Service (which is not a true IoC container but more of a service locator, but it does work to allow you to call platform specific code from a .NET Standard or PCL library project, which is ultimately what you want to do).



        That said, there is another option for your core Xamarin.Forms code and that is to use a Shared Library project type. .NET Standard is by far the more common and the option that is suggested when you follow the getting started docs for Xamarin.Forms (and Xamarin.Forms != Xamarin see (1) below) You can select this when you create your Xamarin.Forms solution:



        enter image description here



        With a Shared library project type for your core Xamarin.Forms code, you will have access to everything that is referenced in your platform specific projects so you will access to everything that you have access to in the Xamarin.iOS and Xamarin.Android projects directly. No IoC or Dependency services are necessary.



        There has always been much debate on whether using a Shared Library project or a .NET Standard project is the best way to go. There are pros and cons to each. In a nutshell using a .NET Standard project forces you to use IoC to call platform specific code from the library project, and use custom renderers to access platform specific properties of UI controls, whereas a Shared Library project give you full access to all the classes and libraries that are available to the platform specific project, making Dependency Injection unnecessary... BUT when using a Shared project, since you can have both Xamarin.Android specific and Xamarin.iOS specific code in the same Shared project, you need to use compiler directives (#if and #endif) so that iOS specific code is only compiled when building the iOS project and Android specific code is only compiled when compiling the Android project. Not doing so can cause compile and/or runtime issues. Here is a simple piece of code to show you how to use the compiler directives to isolate iOS and Android specific code. This simple sample will create a button that when tapped will present an Alert. How to present an Alert is different between iOS and Android so we need to isolate those bits of code in the button click event handler so the correct code runs on the correct platform.



        First define the compiler symbols in the Project Options. Right click on the Android project and select Project Options and select Compiler on the left. Then in the Define Symbols field, add ANDROID;, e.g.:



        enter image description here



        Then do the same for the iOS project (but entering IOS obviously):



        enter image description here



        It is worth noting that this is a configuration dependent setting, so you need to add these symbols for all of the configurations that you will use to build your projects.



        Next create the button in MainPage.xaml:



        <Button Text="Show me an alert!" 
        HorizontalOptions="Center"
        VerticalOptions="CenterAndExpand"
        Clicked="Handle_Clicked" />


        Then in the MainPage.xaml.cs code behind file:



            void Handle_Clicked(object sender, System.EventArgs e)
        {
        #if ANDROID
        Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
        #endif
        #if IOS
        var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
        alert.Show();
        #endif
        }


        You will also need the compiler directives around the using statements:



        #if ANDROID
        using Android.Widget;
        using SharedSample.Droid;
        #endif
        #if IOS
        using UIKit;
        #endif


        So hopefully now you better understand how to make cross platform apps and some of the challenges around sharing code and using platform specific code. All that said, you still will not be able to add a native iOS page (or native Android page) to your Xamarin.Forms MainPage property since the iOS page is NOT a Xamarin.Form page (MainPage can only accept a subclass of a Xamarin.Forms Page), but this should show you how to call platform specific code from your shared code.



        Oh, now I see in your screenshots that you added your Xamarin.Forms XAML page to the iOS project???? No, that is not the way around your issue. I would seriously suggest you sign up for Xamarin University. You need more than just code snippets, you need to better understand cross-platform development and my not-so-brief primer here is not nearly enough to get you going from what I can see.



        BUt you know what, I think there is a OAuth library for Xamarin Forms, so maybe you can make that work as it should do all the platform specific stuff for you.
        Nuget page: https://www.nuget.org/packages/Xamarin.Auth/
        Github page: https://github.com/xamarin/Xamarin.Auth
        Docs: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth



        Good luck!



        (1) Xamarin was a company that was purchased by Microsoft. Xamarin made SDKs that allowed making apps for iOS, Mac, and Android using C# and the .NET framework. Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono which is an open source port of .NET (since .NET only ran on Windows and other Microsoft platforms at the time... though there is now .NET Core that is cross-platform... but that is another topic).
        Later Xamarin introduced Xamarin.Forms which is a cross-platform UI (User Interface) library that allows creating the UI in common code and/or XAML. Prior to Xamarin.Forms, the UI for each platform had to be created in the platform specific projects, i.e. the UI for iOS would be in Xamarin.iOS project, UI for Android would be in Xamarin.Android project, etc., but all could call into back end code (i.e. web requests, models, etc.) that resides in one shared library project, allowing about 80% of the total code to be shared between the different platform app projects. With Xamarin.Forms, for a simple app, 100% code sharing is possible. Xamarin.Forms does still use Xamarin.iOS and Xamarin.Android projects, as well as UWP projects on Windows, to kick off the UI, but Xamarin.Forms uses renderers to render the Xamarin.Forms UI Controls into platform specific controls, i.e. a Button in Xam.Forms renders to a UIButton on iOS and an Android Button on Android. However Xamarin.Forms only gives you access to core common properties of the native controls, so if you need to access specific native properties or features, you have to use a custom renderer (to modify UI controls on the native platform and have access to native control's properties) and/or dependency service (to run platform specific code from the core Xam.Forms library project).






        share|improve this answer












        Using an IoC (Inversion of Control) is one way to go as pointed out by Shawn, but understand that IoC is a name for one method of calling into platform specific code from a platform agnostic library project like a .NET Standard project. You have to decide on what IoC library to use, or whether to use IoC functionality that is built into some cross-platform frameworks like MvvmCross or even Xamarin.Forms Dependency Service (which is not a true IoC container but more of a service locator, but it does work to allow you to call platform specific code from a .NET Standard or PCL library project, which is ultimately what you want to do).



        That said, there is another option for your core Xamarin.Forms code and that is to use a Shared Library project type. .NET Standard is by far the more common and the option that is suggested when you follow the getting started docs for Xamarin.Forms (and Xamarin.Forms != Xamarin see (1) below) You can select this when you create your Xamarin.Forms solution:



        enter image description here



        With a Shared library project type for your core Xamarin.Forms code, you will have access to everything that is referenced in your platform specific projects so you will access to everything that you have access to in the Xamarin.iOS and Xamarin.Android projects directly. No IoC or Dependency services are necessary.



        There has always been much debate on whether using a Shared Library project or a .NET Standard project is the best way to go. There are pros and cons to each. In a nutshell using a .NET Standard project forces you to use IoC to call platform specific code from the library project, and use custom renderers to access platform specific properties of UI controls, whereas a Shared Library project give you full access to all the classes and libraries that are available to the platform specific project, making Dependency Injection unnecessary... BUT when using a Shared project, since you can have both Xamarin.Android specific and Xamarin.iOS specific code in the same Shared project, you need to use compiler directives (#if and #endif) so that iOS specific code is only compiled when building the iOS project and Android specific code is only compiled when compiling the Android project. Not doing so can cause compile and/or runtime issues. Here is a simple piece of code to show you how to use the compiler directives to isolate iOS and Android specific code. This simple sample will create a button that when tapped will present an Alert. How to present an Alert is different between iOS and Android so we need to isolate those bits of code in the button click event handler so the correct code runs on the correct platform.



        First define the compiler symbols in the Project Options. Right click on the Android project and select Project Options and select Compiler on the left. Then in the Define Symbols field, add ANDROID;, e.g.:



        enter image description here



        Then do the same for the iOS project (but entering IOS obviously):



        enter image description here



        It is worth noting that this is a configuration dependent setting, so you need to add these symbols for all of the configurations that you will use to build your projects.



        Next create the button in MainPage.xaml:



        <Button Text="Show me an alert!" 
        HorizontalOptions="Center"
        VerticalOptions="CenterAndExpand"
        Clicked="Handle_Clicked" />


        Then in the MainPage.xaml.cs code behind file:



            void Handle_Clicked(object sender, System.EventArgs e)
        {
        #if ANDROID
        Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
        #endif
        #if IOS
        var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
        alert.Show();
        #endif
        }


        You will also need the compiler directives around the using statements:



        #if ANDROID
        using Android.Widget;
        using SharedSample.Droid;
        #endif
        #if IOS
        using UIKit;
        #endif


        So hopefully now you better understand how to make cross platform apps and some of the challenges around sharing code and using platform specific code. All that said, you still will not be able to add a native iOS page (or native Android page) to your Xamarin.Forms MainPage property since the iOS page is NOT a Xamarin.Form page (MainPage can only accept a subclass of a Xamarin.Forms Page), but this should show you how to call platform specific code from your shared code.



        Oh, now I see in your screenshots that you added your Xamarin.Forms XAML page to the iOS project???? No, that is not the way around your issue. I would seriously suggest you sign up for Xamarin University. You need more than just code snippets, you need to better understand cross-platform development and my not-so-brief primer here is not nearly enough to get you going from what I can see.



        BUt you know what, I think there is a OAuth library for Xamarin Forms, so maybe you can make that work as it should do all the platform specific stuff for you.
        Nuget page: https://www.nuget.org/packages/Xamarin.Auth/
        Github page: https://github.com/xamarin/Xamarin.Auth
        Docs: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth



        Good luck!



        (1) Xamarin was a company that was purchased by Microsoft. Xamarin made SDKs that allowed making apps for iOS, Mac, and Android using C# and the .NET framework. Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono which is an open source port of .NET (since .NET only ran on Windows and other Microsoft platforms at the time... though there is now .NET Core that is cross-platform... but that is another topic).
        Later Xamarin introduced Xamarin.Forms which is a cross-platform UI (User Interface) library that allows creating the UI in common code and/or XAML. Prior to Xamarin.Forms, the UI for each platform had to be created in the platform specific projects, i.e. the UI for iOS would be in Xamarin.iOS project, UI for Android would be in Xamarin.Android project, etc., but all could call into back end code (i.e. web requests, models, etc.) that resides in one shared library project, allowing about 80% of the total code to be shared between the different platform app projects. With Xamarin.Forms, for a simple app, 100% code sharing is possible. Xamarin.Forms does still use Xamarin.iOS and Xamarin.Android projects, as well as UWP projects on Windows, to kick off the UI, but Xamarin.Forms uses renderers to render the Xamarin.Forms UI Controls into platform specific controls, i.e. a Button in Xam.Forms renders to a UIButton on iOS and an Android Button on Android. However Xamarin.Forms only gives you access to core common properties of the native controls, so if you need to access specific native properties or features, you have to use a custom renderer (to modify UI controls on the native platform and have access to native control's properties) and/or dependency service (to run platform specific code from the core Xam.Forms library project).







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 2:23









        jgoldberger

        2,9131723




        2,9131723
























            up vote
            0
            down vote













            Your base project cannot reference the platform specific project. If you could do that, you would be back in the boat of using platform specific libraries on the wrong platform.



            Instead, you need to create a class or interface in your base project that each of your platform specific projects can extend. This way, you can pass that base class between projects without needing to know about any of the platform specific libraries that are being used.



            I would recommend an IoC (Inversion of Control) pattern for this situation. It abstracts the reference handling for you and simplifies the registration of your various services. Take a look at this article which is solving the exact same type of situation.



            I hope this helps!






            share|improve this answer





















            • Sorry, still not sure how IoC's should be implemented to help in my situation. If you could please explain it that would be great!
              – Mohamed Al Sabbagh
              Nov 21 at 23:09















            up vote
            0
            down vote













            Your base project cannot reference the platform specific project. If you could do that, you would be back in the boat of using platform specific libraries on the wrong platform.



            Instead, you need to create a class or interface in your base project that each of your platform specific projects can extend. This way, you can pass that base class between projects without needing to know about any of the platform specific libraries that are being used.



            I would recommend an IoC (Inversion of Control) pattern for this situation. It abstracts the reference handling for you and simplifies the registration of your various services. Take a look at this article which is solving the exact same type of situation.



            I hope this helps!






            share|improve this answer





















            • Sorry, still not sure how IoC's should be implemented to help in my situation. If you could please explain it that would be great!
              – Mohamed Al Sabbagh
              Nov 21 at 23:09













            up vote
            0
            down vote










            up vote
            0
            down vote









            Your base project cannot reference the platform specific project. If you could do that, you would be back in the boat of using platform specific libraries on the wrong platform.



            Instead, you need to create a class or interface in your base project that each of your platform specific projects can extend. This way, you can pass that base class between projects without needing to know about any of the platform specific libraries that are being used.



            I would recommend an IoC (Inversion of Control) pattern for this situation. It abstracts the reference handling for you and simplifies the registration of your various services. Take a look at this article which is solving the exact same type of situation.



            I hope this helps!






            share|improve this answer












            Your base project cannot reference the platform specific project. If you could do that, you would be back in the boat of using platform specific libraries on the wrong platform.



            Instead, you need to create a class or interface in your base project that each of your platform specific projects can extend. This way, you can pass that base class between projects without needing to know about any of the platform specific libraries that are being used.



            I would recommend an IoC (Inversion of Control) pattern for this situation. It abstracts the reference handling for you and simplifies the registration of your various services. Take a look at this article which is solving the exact same type of situation.



            I hope this helps!







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 21 at 22:42









            Shawn Lehner

            1,260612




            1,260612












            • Sorry, still not sure how IoC's should be implemented to help in my situation. If you could please explain it that would be great!
              – Mohamed Al Sabbagh
              Nov 21 at 23:09


















            • Sorry, still not sure how IoC's should be implemented to help in my situation. If you could please explain it that would be great!
              – Mohamed Al Sabbagh
              Nov 21 at 23:09
















            Sorry, still not sure how IoC's should be implemented to help in my situation. If you could please explain it that would be great!
            – Mohamed Al Sabbagh
            Nov 21 at 23:09




            Sorry, still not sure how IoC's should be implemented to help in my situation. If you could please explain it that would be great!
            – Mohamed Al Sabbagh
            Nov 21 at 23:09


















             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421353%2fhow-to-reference-class-from-ios-project-to-the-main-project-in-xamarin%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Trompette piccolo

            Slow SSRS Report in dynamic grouping and multiple parameters

            Simon Yates (cyclisme)