Add a macOS project to your existing solution

With the new version of Xamarin, we can create apps for macOS. But how can I add a macOS project to my solution? I explain step by step what we have to do.

Add new project

The first step is to add a new project for macOS in your solution. Right-click on your solution and select Add New project... Step 1 - Add new project

Now select from the list App under Mac and then Cocoa App.Step 2 - Select project type

Then name your project, usually, we call this project with yourprojectname.macOS. Step 3 - Name your project

How you see in the preview, the name in the dock it is not very nice. Then we can change it: check Use a Different App Name in Dock and then type the app name.Step 4 - Change name for dock

At the end select the folder where you want to save your project, usually, in the root of your folder in the filesystem.Step 5 - Select project folder

Add packages

In your new project add under Packages Xamarin.Forms and all your other packages you are using in the other project.

Now we have to add the main project. Under References, select the main project and the other dependencies. Edit references

Update the code

Now the complicated part is starting. In your Info.plist file, we have to remove NSMainStoryboardFile.Edit Info.plist

Now in your macOS project, we have to delete Main.storyboard because we don't need it anymore. Right-click on Main.storyboard and then select Remove.

Main.storyboard in your projectMain.storyboard delete

Open your Main.cs and change the Main function with the following code:

static class MainClass
{
    static void Main(string[] args)
    {
        NSApplication.Init();
        NSApplication.SharedApplication.Delegate = new AppDelegate();
        NSApplication.Main(args);
    }
}

Open AppDelegate.cs and add at the top the following packages:

using Xamarin.Forms;
using Xamarin.Forms.Platform.MacOS;

You see now AppDelegate derives from NSApplicationDelegate. Change NSApplicationDelegate with FormsApplicationDelegate. Now you see that AppDelegate is underlined with a red line. We take care of that shortly.

Now add in the AppDelegate body 

NSWindow window;

We override MainWindow function (Visual Studio helps to create this function with the correct signature). As return, we use window.

public override NSWindow MainWindow
{
    get
    {
        return window;
    }
}

Now we have to display a window. For that we have to change AppDelegate(). For creating a window, we have to define its style and dimension.

public AppDelegate()
{
    var style = NSWindowStyle.Closable | NSWindowStyle.Resizable | 
                NSWindowStyle.Titled;
    var rect = new CoreGraphics.CGRect(100, 100, 1024, 768);

    window = new NSWindow(rect, style, NSBackingStore.Buffered, false);
    window.Title = "WordBank Easy";
    window.TitleVisibility = NSWindowTitleVisibility.Hidden;
}

The last thing to do, it is the inizialization of Xamarin.Forms and your app. We change now DidFinishLaunching

public override void DidFinishLaunching(NSNotification notification)
{
    Forms.Init();
    LoadApplication(new App());

    base.DidFinishLaunching(notification);
}

Pretty easy, isn't it? Here my complete code of AppDelegate.cs

using AppKit;
using Foundation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.MacOS;

namespace WordBankEasy.macOS
{
    [Register("AppDelegate")]
    public class AppDelegate : FormsApplicationDelegate
    {
        NSWindow window;

        public override NSWindow MainWindow
        {
            get
            {
                return window;
            }
        }

        public AppDelegate()
        {
            var style = NSWindowStyle.Closable | 
                        NSWindowStyle.Resizable | 
                        NSWindowStyle.Titled;
            var rect = new CoreGraphics.CGRect(100, 100, 1024, 768);

            window = new NSWindow(rect, style, NSBackingStore.Buffered, 
                                  false);
            window.Title = "WordBank Easy";
            window.TitleVisibility = NSWindowTitleVisibility.Hidden;
        }

        public override void DidFinishLaunching(
                                NSNotification notification)
        {
            Forms.Init();
            LoadApplication(new App());

            base.DidFinishLaunching(notification);
        }

        public override void WillTerminate(NSNotification notification)
        {
            // Insert code here to tear down your application
        }
    }
}

Happy coding!

Xamarin forms, UWP Windows 10 App, TitleBar and Status bar customization

Customize the title bar of your Universal App for Windows 10 is quite easy, but you need to write different code for PC and Mobile. The class that allows you to customize the title bar:

  • when running on a PC is called TitleBar
  • when running on a Mobile is called StatusBar

Before to call the API you first need to check if it exists (true if you are running on that platform):

//PC customization
if (ApiInformation.IsTypePresent(
                   "Windows.UI.ViewManagement.ApplicationView"))
{
    var titleBar = ApplicationView.GetForCurrentView().TitleBar;
    if (titleBar != null)
    {
        titleBar.ButtonBackgroundColor = Colors.DarkBlue;
        titleBar.ButtonForegroundColor = Colors.White;
        titleBar.BackgroundColor = Colors.Blue;
        titleBar.ForegroundColor = Colors.White;
    }
 }

//Mobile customization
if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{

    var statusBar = StatusBar.GetForCurrentView();
    if (statusBar != null)
    {
        statusBar.BackgroundOpacity = 1;
        statusBar.BackgroundColor = Colors.DarkBlue;
        statusBar.ForegroundColor = Colors.White;
    }
}

You could receive an error

StatusBar doesn't exist in context

You resolve it to add in the reference for UWP project Windows Mobile Extensions for the UWP and Windows Desktop Extensions for the UWP.

Extensions

Happy coding!

Add Calabash to your Xamarin project

Why add Calabash to your project? Because without it you can't test your application with Xamarin Test Cloud.

Scenario

I created my app for iOS and I want to test it on Xamarin Cloud. First thing I have to install to create a UITest easily is Xamarin Test Recorder. When I opened this application, I was confuse because nobody explain what kind of app I can choose. Basically if you have a iOS project, before use Xamarin Test Recorder, you must create an .ipa and it means you have to create an archive and publish it.

After createing a UITest project you can sent it with Export function directly to TestCloud. The problem I discovered is

Errors and Failures:
1) SetUp Error : RecorderTest.NewTest
   SetUp : System.Exception : Unable to contact test backend running in app. A common cause is that the app is not properly linked with Calabash. Please verify that it includes the Calabash component.
  at Xamarin.UITest.iOS.iOSAppLauncher.EnsureCalabashRunning (ICalabashConnection connection) <0x7507b30 + 0x0005f> in <filename unknown>:0 
  at Xamarin.UITest.iOS.iOSAppLauncher.LaunchApp (IiOSAppConfiguration appConfiguration, Xamarin.UITest.Shared.Http.HttpClient httpClient, Xamarin.UITest.TestCloud.TestCloudiOSAppConfiguration testCloudAppConfiguration, Xamarin.UITest.Shared.Http.HttpClient testCloudWsClient, Xamarin.UITest.Shared.Http.HttpClient xtcServicesClient, Boolean testCloudUseDeviceAgent) <0x6cbb340 + 0x0019b> in <filename unknown>:0 
  at Xamarin.UITest.iOS.iOSApp..ctor (IiOSAppConfiguration appConfiguration, IExecutor executor) <0x6b39778 + 0x00b03> in <filename unknown>:0 
  at Xamarin.UITest.iOS.iOSApp..ctor (IiOSAppConfiguration appConfiguration) <0x6b39738 + 0x0001f> in <filename unknown>:0 
  at Xamarin.UITest.Configuration.iOSAppConfigurator.StartApp (AppDataMode appDataMode) <0x6b38e18 + 0x00063> in <filename unknown>:0 
  at RecorderTest.SetUp () <0x6b37f70 + 0x0004f> in <filename unknown>:0 
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x31e7110 + 0x00093> in <filename unknown>:0 

Why this? Because I didn't install Calabash.

Add Calabash for iOS

First al all, open your Terminal with admin privileges. Then execute this script:

gem install calabash-cucumber gem install calabash-android gem install xamarin-test-cloud

Now in your system there are the basic for Calabash.

Now you can install a Calabash sandbox. Do not use sudo to install the Calabash Sandbox. Execute this script

curl -sSL https://raw.githubusercontent.com/calabash/install/master/install-osx.sh | bash

Now in the directory of your iOS project execute this script:

calabash-ios download

And finally you can generate a feature folder. The features folder is a special folder where Cucumber expects the test code to reside. Calabash can create this folder and provide some boilerplate code to get us started.

The last step is to execute in your iOS project the following command in the Terminal

calabash-ios gen

Now you create a new .ipa and do a new test. This time it will work!

Happy coding!

An error occurs with MobileCenter for Xamarin iOS

I added Microsoft Mobile Center to my project after creating the app there. On MobileCenter documentation you can know the Install Identifier for your application (MobileCenter documentation is here).

System.Guid installId = MobileCenter.InstallId;

This function is working fine if you have Android or iOS 10. With iOS less than 10 an error occurs:

Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).

and the StackTrace is similar to

at System.Guid+GuidResult.SetFailure (System.Guid+ParseFailureKind failure, System.String failureMessageID, System.Object failureMessageFormatArgument, System.String failureArgumentName, System.Exception innerException) [0x00030] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.123/src/mono/mcs/class/referencesource/mscorlib/system/guid.cs:198 \n at System.Guid+GuidResult.SetFailure (System.Guid+ParseFailureKind failure, System.String failureMessageID) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.123/src/mono/mcs/class/referencesource/mscorlib/system/guid.cs:184 \n at System.Guid.TryParseGuidWithDashes (System.String guidString, System.Guid+GuidResult& result) [0x0008f] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.123/src/mono/mcs/class/referencesource/mscorlib/system/guid.cs:695 \n at System.Guid.TryParseGuid (System.String g, System.Guid+GuidStyles flags, System.Guid+GuidResult& result) [0x00115] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.123/src/mono/mcs/class/referencesource/mscorlib/system/guid.cs:443 \n at System.Guid.Parse (System.String input) [0x00021] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.123/src/mono/mcs/class/referencesource/mscorlib/system/guid.cs:262 \n at Microsoft.Azure.Mobile.MobileCenter.get_InstallId () [0x0000a] in :0 \n at myInventories.Helpers.LogHelpers.SendMessageToAzure (System.String EventName, System.String PageName, System.String BaseClass, myInventories.Logs.ActionType Action, System.String MoreInfo, System.Collections.Generic.Dictionary`2[TKey,TValue] DictionaryInfo) [0x00008] in /Users/enricorossini/Projects/myInventories/myInventories/myInventories/Helpers/LogHelpers.cs:72

To avoid this error you have to check the OS version.

Implementation

In your solution you have to add in all projects Device Information Plugin (for NuGet Xam.Plugin.DeviceInfo). Then you check easily the OS version with

// check the OS version to avoid error on MobileCenter
string MobileId = "";
var osInfo = CrossDeviceInfo.Current;
if ((osInfo.Platform == Plugin.DeviceInfo.Abstractions.Platform.iOS) && 
    (osInfo.VersionNumber.Major < 10)) 
{
    MobileId = "Unknown";
}
else {
    MobileId = MobileCenter.InstallId.ToString();
}

Happy coding!

Preserve data when deploying Xamarin.Android app

By default all your data from your previous runs is deleted when you’re deploying an Xamarin.Android app. In many cases you don’t want the data to be deleted.

Visual Studio


To preserve data go to Tools -> Options -> Xamarin -> Android Settings and check “Preserve application data/cache on device between deploys”.

Preserve_data_visualstudio

Xamarin Studio


To preserve data go to Tools -> Options -> Android and check “Preserve data/cache between application deploys”.

Preserve_data_xamarinstudio

Happy coding!

Visual Studio updates Xamarin

When you open Visual Studio 2015 and there is a pop windows to invite you to click on it for updating Xamarin and you click, nothing happends. There is a bug but clicking the update available popup was fixed in one of the recent releases. You can manually update in the Options menu under Tools.

As for the errors, I get those all the time. Support packages can often be a problem. Update to the latest XF package. Try deleting bin, obj, and the contents of packages folders and rebuild.

Visual-Studio-Update-Xamarin

Xamarin Studio: complete uninstall on Mac

Remove these directories:

/Applications/Xamarin Studio.app
/Developer/MonoTouch
/Developer/MonoAndroid
/Library/Frameworks/Mono.framework
/Library/Frameworks/Xamarin.Mac.framework
/Library/Frameworks/Xamarin.Android.framework

Locations in your user directory:

~/Library/Caches/Xamarin
~/Library/Caches/XamarinStudio-4.0
~/Library/Developer/Xamarin
~/Library/Developer/XamarinStudio
~/Library/Logs/Xamarin
~/Library/Logs/XamarinStudio-4.0
~/Library/Preferences/Xamarin
~/Library/Preferences/XamarinStudio-4.0
~/Library/Xamarin
~/Library/Xamarin.Mac
~/Library/MonoTouch
~/Library/MonoAndroid
~/Library/XamarinStudio-4.0

That's all there is afaik.

Advertsing

125X125_06





TagCloud

MonthList

CommentList