I have previously developed a Windows Universal App.
I would like to migrate all the non-platform specific code to place in a portable class library project for further development.How to achieve this?
In the Windows Universal App there are some backend C# code controlling UI contents and manipulate the data as well. I may not able to seperate the non-platform specific code nicely. Can I still migrate to PCL project in this case?
I searched on the portable class library documentation as the link below:
https://msdn.microsoft.com/library/gg597391.aspx
The description looks confusing. Does it mean that I just include my previous app package in the PCL project and then everything works?
How to Migrate
Unless you changed your question title to "how can I move platform independent portion of my code to PCL", I believe no others can easily understand your meaning.
I assume that you already have a Windows Universal app project in Visual Studio. Then to move code to PCL,
Simply create an empty PCL project (choose a proper profile), and add it as a reference to your original Windows Universal app project.
Cut (not copy) and paste some source files from your app project to this PCL project.
Compile the solution and fix issues.
If you don't know what is a PCL profile, read MSDN related materials. If you don't know which source files should go to PCL, and which should remain in app project, do experiments or check out other guys' sample project.
About The Confusion You Got
I can only say to understand what you highlighted, you should read carefully what is not highlighted in the same sentence, and the subtitle.
Clearly when you have a PCL project, and a Windows Store/Phone app project that references the PCL, when you generate the deployment package (.appx) in Visual Studio, the final package will include every needed assemblies.
It obviously isn't what you described.
You will need to extract the platform specific code. The docs you quote go in the other direction: the PCL is included in the appx package, not the app package in the PCL.
Depending on how entrenched the platform specific code is you may be able to separate it out via inversion of control: define an interface the PCL can use to call back into the host to acquire platform specific data which the PCL can then manipulate.
For example, if the current code has platform specific code to open a file and get its contents, the PCL could call a funtion in the host which opens a file and returns a stream to the contents.
Related
This is a question for which I need someone to give me some pointers and point me in the right direction. Not a "suggest-a-sulution-code" question:
How do I create a stand-alone release of a C# Windows Froms application that uses a couple of NuGet packages AND an external library (AutoIT)?
The application is a simple forms application which uses Selenium Webdriver for opening and accessing a browser. In addition to this, it uses a library called AutoIt, for handling windows operations.
In my VS project I've installed Selenium Webdriver with NuGet, and added the AutoIt libraries manually as externals.
The resulting .exe file created after build does not work on another computer when I just copy it over. The GUI and functionality works, but the AutoIt library is not included. This is probably logical, and due to my lack of knowledge regarding building windows applications. But how do I do this? How do I build a release which can be used by others, which includes any external libraries used by the application? Do I have to manually get all DLL files relatedt to the project, or is there a way to package things to make it easier?
In a Xamarin.Forms project I have a file icon.png in each of the Resources/drawable folders of the droid project. BuildAction is AndroidResource. I use this file in various places in the project and they appear just fine.
Now I am trying to use it as the small icon for notifications. In the PCL project the small icon is set like this in the example code I am using:
.SetSmallIcon(Android.Resource.Drawable.SymActionEmail)
I was sort of expecting icon to be shown in the Resource.Drawable Intellisense chooser, but it is not, so Android.Resource.Drawable.icon results in 'Resource.Drawable' does not contain a definition for 'icon'.
I tried adding a resx file to the PCL project, but VS will only let me add strings to that file, not images.
How do I use icon instead of SymActionEmail?
Use Resource.Drawable.icon instead of Android.Resource.Drawable.icon. With the Android prefix, you're referring to this list of predefined resources, not the ones in your project.
Edit: Instead of commenting, I decided to write here because it's easier to read.
SetSmallIcon() is a method in the Notification.Builder class from the Android API. You should never call platform specific code directly from the PCL project. Also, that's the reason you shouldn't even be able to call Android.Resource.Drawable resources from the PCL. Have you added a reference to Xamarin.Android or something?
The correct way to call platform specific code from a PCL is to (for example) create an interface in the PCL, which is then implemented in each platform specific project. Here's an excerpt from the Xamarin documentation:
Using either interfaces or base classes defined in the shared code and implemented or extended in platform-specific projects. Writing and extending shared code with class abstractions is particularly suited to Portable Class Libraries because they have a limited subset of the framework available to them and cannot contain compiler directives to support platform-specific code branches.
Handling Platform Divergence & Features
Also, to your question about setting the notification inside the PCL: Doesn't setting the notification inside one of the platform specific projects sort of break the purpose of using Xamarin.Forms in the first place?
In short, no it doesn't. Xamarin.Forms isn't meant to be able to do everything in a single project, that's why you still have separate projects for iOS, Android and UWP. Anything that requires platform specific libraries or functinality should be implemented in the platform specific project but can still be called from the PCL by using abstraction.
I am having a lot of problems when trying to integrate Parse with cross-platform Xamarin app. At first, I was able to create Android app using Xamarin and MvvmCross and integrate with Parse service (done by adding Parse component in Xamarin). When it comes time to develop iOS app, I am having problem to refactor out Parse dependency into Core PCL project, since Parse currently doesn't support Xamarin PCL projects. Hence, there is no Parse NuGet package or Xamarin component that can be added to PCL project. I can easily add Parse component to iOS project and Android project respectively, but that will require lots of code duplication across both projects.
I've read that referencing Parse.dll and Parse.NetFx45.dll in Core project enables me to use Parse calls in Core project. I did this and are able to compile everything successfully. However, when I try to initialize Parse in Core project using ParseClient.Initialize("ApplicationID", "DotNetKey");, I get TypeInitializationException during runtime.
Question is, what is the best way to integrate Parse service with Xamarin & MvvmCross cross-platform application? I'd imagine lots of people would have done this, but couldn't find references/examples. Duplicating codes across both iOS and Android project definitely shouldn't be the way to go.
Here are a couple of ideas:
First, if you are currently manually copying Parse code changes from project to project, you could speed up that process by writing a script that you run that would clone certain files to the other project. Or you could maybe write a grunt script that copies files automatically when it detects a change.
Now, here is another approach that stores Parse code in one project but is shared across platforms:
The Problem: I was using a Shared Project instead of a PCL to house my Xamarin.Forms and Parse code. The Parse code was working just fine, but I ran into an issue when trying to use my own custom ContentView in my ContentPage in XAML. I wanted a solution that would allow my custom ContentView to work as well as my Parse code -- both from the same project.
The Solution: I have switched to now housing my Xamarin.Forms and Parse code in a PCL. But there is a small catch. Before I explain the catch, just know that it does work with NO Parse code duplication (except for the one line of Parse initialization code that goes in each platform's specific project).
What's the catch? The catch is that in your portable class library you have to manually swap in and out either the Parse.iOS.dll or Parse.Android.dll depending on what you are compiling for at the time.
Does it increase the file size? No. I tested with my app using a Shared Project (where it uses the platform project's referene to the Parse dll) versus a Portable Class Library (where you have to add a reference to the dll in the platform's project as well as the PCL) and found no increase in the app file size by doing it this way.
Below is the project structure that is currently working for me (with project names renamed for confidentiality). (FYI: I am using Xamarin for Mac.)
MyProject.iOS
- Reference to Parse.iOS.dll
- Reference to the Portable Class Library
MyProject.Android
- Reference to Parse.iOS.dll
- Reference to the Portable Class Library
Portable Class Library
- Parse Code
- Xamarin Forms Code
- Reference to either Parse.iOS.dll or Parse.Android.dll
Important: When swapping out the DLL in the PCL, I found that if I right-click the DLL under the References menu, and then click Delete, it caused issues in my project where the iOS project wouldn't compile anymore because it was still looking for the Parse.Android.dll or vice-versa. I tried cleaning the solution, deleting bin and obj folders from the solution's file system to no avail. I got it to work again by doing this: Right-click References, click Edit References, and then uncheck the one Parse DLL and check the box for the other. However, then after that, I tried the "Delete" method again and didn't have problems compiling. Who knows, maybe that issue will crop up for me again.
Won't this get annoying? Depending on how often you switch between platforms, the manual swapping of DLLs may or may not get annoying. No matter how annoying that is though, it can't be worse than having duplicate code. (Perhaps this swapping process could be automated with a script? I think you'd have to unload the PCL and reload it though if you modify the .csproj with a script. Anyone out there up for the challenge? Or perhaps there is a way to do a conditional reference to the DLL based on the platform it is compiling for. Thoughts anyone?)
I hope this helps. If you like any of these ideas better than what you are currently doing please accept this as the answer and let us know which route you decide to take.
Isn't the best way to to this, to create a Parse Plugin for Mvvmcross? Where you define your interfaces that want to use.
And in each platform specific library you reference the parse dll and call the method. So in you Core project you should be able to call the IParse.methods...
So I got it working fine on both Android and iOS by referencing Parse.Android.dll in all 3 projects (Core, iOS, and Android). Yes it sounds weird, but that's what's working for me. Just go to Parse download page and download Xamarin SDK under Android section. It works wonders too! No code duplications, no mess :)
I'm very new to Xamarin. I have a few published Windows Store apps and want to convert them to Android. I'm attempting to use Xamarin for this. I'm just using the free version of Xamarin. Here's where I am so far:
I am trying two apps - one was build with Monogame and one is just build on the WinRT framework.
I have managed to get them both into Xamarin studio, basically by hacking the csproj files.
I'm getting build errors because it's missing references. There does appear to be some equivalent Mono / .Net4 libraries, but things like Storage seem to be missing.
So, my question is: am I going about this the right way and, if so, am I missing a step ("convert dependencies" or something)?
If I'm not going about this the right way then how should I be doing this (I found very few online resources on this subject)?
EDIT:
The following are some specific errors that I'm getting from the Xamarin App:
And my references:
EDIT:
After some further research, the only dependency I can't explain as missing is Microsoft.Xna.*. The others all have different implementations on Android / iOS.
You will be able to use much of your existing code with Xamarin.
However, the errors you are getting with those specific libraries are because they do not exist for Xamarin in iOS and Android. So whatever functionality you had you will need to rework using libraries that are available.
For example, instead of using Windows.Storage you would use Android.OS.Storage.
See their documentation for details:
http://androidapi.xamarin.com/index.aspx?link=N%3AAndroid.OS.Storage
Edit
For XNA all of that should port fine if you use MonoGame:
https://github.com/mono/MonoGame/wiki
I'm not sure why it's not bundled in Xamarin, but that will hook you up.
Edit
This is taken from Xamarin documentation found here: http://developer.xamarin.com/guides/cross-platform/cocos2d_xna/cocos2dxna_tutorial/
After creating the project, you need to add the various Cocos2D-XNA dependencies to the solution. Add the following projects from the location where you downloaded the Cocos2D-XNA and MonoGame source:
box2d.iOS – 2D physics library. We’ll use this in later tutorials.
cocos2d.iOS – Cocos2D-XNA for iOS.
Lidgren.Network.iOS – Networking library used by MonoGame.
MonoGame.Framework.iOS – MonoGame for iOS.
This video may answer your question. You will most likely need to replace the reference with a PCL equivalent if one exists.
http://developer.xamarin.com/videos/cross-platform/any/
I have a Xamarin Solution were I have two different iOS projects in it - but both of these are sharing the same static content (HTML, JS, CSS++). I'd love to be able to use a target file or similar to be able to include a common file holding a reference to all these files.
When I try and add a directive - it does not seem to respect that at all, not in Xamarin studio, nor when I actually build.
You should be able to make an iOS class library project and include these files in it with a build action of BundleResource. I generally do this with binding projects where the Obj-C library includes a bunch of files you need to include with your app (it works for normal libraries, too though).
When referencing the library, it should copy the files to your application bundle. Keep in mind, however, you probably need to actually have some code in the class library you are calling from the main iOS application project. Xamarin.iOS may strip out the library if code inside is not being used.