http://www.microsoft.com/en-us/download/details.aspx?id=42307
I opened up the new project window and with a little searching around this is what I found:
There are four new project types:
- Blank App (Universal App) - Very simple solution to create two projects (Windows Store and Windows Phone 8.1) and one shared universal project with a nifty new icon
- Hub App (Universal App) - Slightly more complex than the Blank app, it still creates a Windows Store and Windows Phone 8.1 projects both using the same shared project
- Class Library (Portable for Universal Apps) - Creates a project to create a Portable Class Library (DLL) in the profile that supports Windows Store 8.1 and Windows Phone 8.1 applications. Currently there are no profiles that support Windows Phone 8.1 and Xamarin so I was not able to make one of these that also supports Xamarin but I suspect this will be updated soon enough. This project type is intended to create libraries that can be shared outside the solution.
- Windows Runtime Component (Portable for Universal App) - Similar to the Class Library type except compiles into a winmd file instead of a dll.
Blank App (Universal App) - This creates a new universal app solution with three projects, One for a Windows Phone 8.1 UI, one with a Windows Store Application and one shared universal application which would seem to be where the interesting bits are.
The new shared app type just shows up with an xaml file and is referenced by both the Windows Store application and the Windows Phone 8.1 application. This is a project type unlike what you may be used to, in fact it appears to be only a repository for shared code that can be used by other projects in the solution. Here are some things that are of interest:
- If you right click on the shared universal project and select properties all you can change is the root namespace. That's it.
- When compiled no DLL is generated for this project, all code in it is compiled directly into the Windows Store and Windows Phone 8.1 applications. These projects cannot be independently be shared or used outside of the projects that directly reference them in a solution.
- You cannot compile only the Shared project on the build menu, it cannot be built independently. This makes sense give that it has no output and is compiled directly into a referencing project.
As of the time of the writing there is no references nor ability to add references to the shared project through the Visual Studio UI. What is available to you within code of these projects is the subset of the .NET framework for this project and that's it. That means no referencing Autofac or any third party library in code through the Visual Studio UI.- EDIT TO PREVIOUS VERSION - The shared project *WILL* pickup references in the projects that reference them. You have to select the proper project in the upper left dropdown when editing a file in the shared project and it will pickup the proper references.
Here is a screenshot of the project selection dropdown where you can select the right platform specific project and get the proper references and conditional compilation symbols:
<Import Project="..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\..
\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" /> <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''"> <Error Condition="!Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This
project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more
information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" /> <Error Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build
restored NuGet packages. Build the project again to include these packages in the build. For more information, see
http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" /> </Target>
using Microsoft.WindowsAzure.MobileServices;
namespace App1
{
class ReferenceTest
{
private MobileServiceClient Test1()
{
return new MobileServiceClient("");
}
}
}
How about Xamarin? As I stated before I couldn't create a Portable Class Library for Universal Apps that also referenced either Xamarin iOS or Android as there did not seem to be a profile for that combination. What about the shared project? I went ahead and added Xamarin iOS and a Xamarin Android UI projects to the solution. I then went to the references section of the Android project and tried to add a reference to App1.Shared like there was in the Windows Store and Windows Phone 8.1 projects. No luck, that wasn't an option when looking at the solution nor could I browse out to a DLL because one does not exist.
I did, however, find the following blog post that states how to modify the project file:
https://medium.com/p/141c2b7bae4f
I took the advice and added the following code to my Android project file in Notepad (As noted in the blog, be careful about the path being correct or your project will not load):
<Import Project="..\App1\App1.Shared\App1.Shared.projitems" Label="Shared" />
When I then reloaded the Android project as the blog post indicated I suddenly has a reference to the shared universal app project.
When I tried to compile I couldn't for two reasons. First the default Blank App added a Xaml file to the shared app, App.xaml. Currently xaml isn't going to be usable by the Android or iOS projects and so can't exist in App1.Shared. I moved this to the individual Windows Store and Windows Phone 8.1 applications (I could also have used pre-compilation directives so it wouldn't be visible to the Android project to the same effect).
The second reason is because the shared project uses the Windows Azure Mobile Services component and my Android project does not reference it. I added this and the problem was resolved (Note: sometimes when getting the Windows Azure Mobile Services package for Xamarin from Nuget it drags along some extra system DLLs that I have to delete: System.IO, System.Runtime and System.Threading.Tasks).
With these issues resolved I am able to use the shared project in Xamarin Android. By following the same steps I am able to do it with the Xamarin iOS project as well.
In conclusion, what have I learned about the present state of Universal Apps and Xamarin?
- Universal PCLs and winmd projects won't work with Xamarin at the present time because there is no profile that supports Windows Phone 8.1 and Xamain project types. I expect that to be resolved.
- Creating a Universal Blank App or Hub app creates a shared project type
- The shared project cannot be created directly through the Visual Studio UI and instead must be created through one of those two project types
- Code in the shared project does not create a DLL or winmd file but instead is compiled directly into the projects that reference the project
There is no way through the Visual Studio UI to add a reference to an external dll to a shared universal project but references can still be added by editing the project file directly- You do not need references in the shared project because it picks up references form the projects that use it. When in a code file you can switch between projects to pick up their references and conditional compilation constants
- All projects that reference the shared universal project must reference and be able to use any code in the shared project or measures such as pre-compilation directives must be used
- Xamarin iOS and Android UI projects can use the shared project but only if their project files are edited directly as there is not currently any way to do it through the Visual Studio UI
In general the shared universal projects would seem to be a new alternative to the old method of simple linking a shared code file between two or more different projects. As is common with that method platform specific differences can be handled via pre-compilation directives. Any sharing of the UX may work on projects that use xaml but of course such code is not currently workable in Xamarin Android and Xamain iOS and would have to be hidden from those project types.
UPDATE: If you want to create a PCL today that targets Windows Phone 8.1 and Xamarin Android and/or Xamarin iOS @danrigby has a great blog post that explains how to do it until an update is released:
http://danrigby.com/2014/04/10/windowsphone81-pcl-xamarin-fix/
I updated the post based on new experimentation with universal applications and understanding how references work. Thanks!
ReplyDelete