Challenges, thoughts, loves, ......

wallymwallym USInsider, Beta ✭✭✭
edited October 2012 in Cross Platform with Xamarin

I'm working on a lot of new material in the area of cross platform mobile with MonoTouch & Mono for Android. I'd like to know your thoughts, challenges, loves, and info in the area of cross platform mobile with MT and MfA. Please just start replying with your input.

Wally

Posts

  • OldRedthOldRedth USMember, Insider ✭✭✭

    I'd agree with @JasonAwbrey

    While it's not exactly 'challenging' to setup a project to work across all mobile platforms, it is a bit tedious. It would be nice if there was a simple way to target iOS, Android, and WP7 more easily from a single project. Even if that's not exactly Portable Class Libraries as we know it.

  • StuartLodgeStuartLodge USBeta ✭✭✭
    edited October 2012

    Yes - definitely - just what @JasonAwbrey and @Redth said...

    Now that VS2012, .Net4.5 and PCLv2 have all shipped, I've gotten a bit further with Portable Class Library work - but still it requires some hideous configuration and csproj hacking to get code working - even with some considerable hacking I still have build issues getting the code to compile quite often!

    As primarily a VS/Resharper user - I find my productivity there maybe 10x that of MonoDevelop - I'm really keen to get this working :)


    Update - clarification - I don't need fully working Portable Class Library support - e.g. I don't need MonoTouch to ship reference libraries and test library conformance to those libraries. I actually quite like the way MonoTouch PCL support already works - which is that it just assumes the library developer knows that what they have made is PCL compliant and then links the Assemblies against MonoTouch regardless :) I just would like that existing PCL support to work a little more smoothly - e.g. for that approach to work more than just for profile1

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai

    We have Portable Class Library support, the problem lies not with supporting it, but practical realities of a PCL architecture. We touch a little on it here: http://docs.xamarin.com/ios/tutorials/Cross_Platform/Building_Cross_Platform_Applications/Part_4_-_Platform_Divergence//Abstraction//Divergent_Implementation.

    But consider the usage of Frank Kruger's (@Praeclarum) SQLite ORM. It supports SQLite on iOS, Android, and Windows Phone 7 (soon to be 8). Platform divergence is handled very simply with IfDefs:

    #if USE_CSHARP_SQLITE
            internal static readonly Sqlite3DatabaseHandle NullHandle = null;
    #else
            internal static readonly Sqlite3DatabaseHandle NullHandle = IntPtr.Zero;
    #endif
    

    However, if you were to use a PCL compliant architecture, you'd have to split this out into three different implementations and either use the Provider Pattern, or Dependency Injection a la the Simple Dependency pattern. Likely what you would wind up with would be an ISqliteORMSomething and three implementations with lots of duplicated code.

    This particular example stems from the fact that the PCL spec doesn't allow pinvokes (and for good reason) - however, in practical usage, you'll run into all kinds of limitations with the PCL.

    In practical reality, what the PCL attempts to solve is having a single class library that you use across multiple platform projects, e.g. MyMobileLib used in android, iOS, WP, etc. There is, however, another way to approach this that makes it considerably easier. What you do is to create a single, standard c# shared library, e.g.:
    MyMobileLibrary
    You can even create an NUnit or MSUnit test project that references this so you can write test cases for it.

    Then, in each platform application you want to use it, you link those files in. If you're using Visual Studio, this is made a lot easier with the Project Linker add-in, because you can just link to that shared library project. I walk through doing it here: http://www.slideshare.net/bryancostanich/crossplatform-mobile-development-in-visual-studio.

    In MonoDevelop, it's slightly more tedious because you have to link each file manually, but it's still a heck of a lot easier than some of the other options.

    By the way, to see this in action, check out the TaskyPro sample here: https://github.com/xamarin/mobile-samples/tree/master/TaskyPro

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai

    Also, stay tuned, very soon we will tasty new bits that will make this all a LOT easier. :D

  • StuartLodgeStuartLodge USBeta ✭✭✭

    Thanks Bryan

    I understand the linker alternative - and I've used it lots in various projects - including trying to use the MSDN Project Linker tool to keep multiple .csproj files in sync.

    I'm also familiar with lots of the old discussions like http://mono-for-android.1047100.n5.nabble.com/sharing-code-between-mono-touch-and-mono-for-android-td5441681.html and http://mono-for-android.1047100.n5.nabble.com/net-versions-why-different-td5521103.html#a5528317

    However, I personally find the PCL solution is better than the shared library solution because:

    • I'm already using dependency injection (and patterns like PlatformAdapter) and prefer injection to #if alternatives
    • the PCL solutoin avoids the manual overhead of maintaining the separate projects - which I've found error prone and tedious in the past - but I look forward to hearing about your new tooling :)
    • PCL allows me to use automated refactoring - while the separate hierarchies in the multiple project solution doesn't - this is one of the key things for me - maybe I rely on R# too much ;)
    • It's great that an increasing number of third party libraries like JSON.Net are now supporting PCL - and it would be awesome for MonoTouch/Droid (IMO) if this could be be further encouraged - it might even mean that we could use portable NuGet imports.

    I've argued this lots - e.g. in: http://www.slideshare.net/cirrious/mvvm-cross-going-portable (and
    http://slodge.blogspot.co.uk/2012/05/portable-class-libraries-in-mvvmcross.html)

    The key picture to me is this one:
    Mvvm Going Portable

    I fully accept that you are arguing that the left-hand side of this is better (more flexible) than the right, and I do understand that getting the right-hand side to work has challenges - especially around PInvoke; around platform specific services like Camera, Location, etc; and around reusing non-PCL third party libraries.

    However, my experience is that the right-hand side is the better solution for writing the code and for longer term code maintenance.

    Regardless of the difference of technical opinion, I don't see why MonoDroid and MonoTouch can't support both the shared code between libraries and the PCL approach - I'm already using them in both platforms extensively and it's only a few small problems like https://bugzilla.xamarin.com/show_bug.cgi?id=7173 which make the portable development a bit of a chore currently. So I'd love to see developers using both approaches.

    Sorry for talking so long - it's because I love my dev :)

    Stuart

  • JasonSteeleJasonSteele GBBeta ✭✭
    edited October 2012

    I second adding @StuartLodge's library to your list of "Other Cross-Platform Libraries". I have been using it for 6 months now and find it essential for enterprise level cross-platform app development.

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai

    @StuartLodge - we'll get that added.

    On the picture above, i think you misunderstood. If you open up the TaskyPro sample, you'll see the exact same thing on the right without PCL, via linking.

    Now, to be clear, i'm not saying you shouldn't use PCLs at all. I'm just saying that many times, you'll run into limitations of it that will never be solved. But if you're already doing dependency injection, etc., the PCL is likely fine for your needs.

    However, @ConceptDev took TaskyPro, did a proper architectural separation, and the thing became unwieldy. It added lots of duplicated code and complexity, and quite honestly, didn't add any real value. I think he has it somewhere, you can/should compare them side by side.

    So, in the end, either choice is valid for you. We do have some basic support for PCLs and it will continue to improve. In fact, we've been working with the PCL team over at MS to provide profiles.

  • StuartLodgeStuartLodge USBeta ✭✭✭

    Thanks Bryan

    No - I didn't misunderstand on TaskyPro - I've tried using that approach :)

    The differences between TaskyPro's approach and the Portable Libraries approach used in the picture are that the PCL approach is proper code reuse, not just file linking, and this helps in:

    • manual maintenance:

      • if you add a file to TaskyPro.Core, then you need to manually add it to each of the other projects
      • if you add a file to the Twitter.Core, then that's it - you're done.
    • automated refactoring:

      • if you rename a method in TaskyPro.Core, then you'll need to manually make the changes in the other projects.
      • if you rename a method in Twitter.Core, then it'll be automatically renamed in the other projects too.

    Now, to be clear, I'm not saying that I haven't hit lots of problems using PCLs... and that's especially true now I'm trying to write Windows8 code! However, I think the PCL2 support is a huge leap forwards - and I got them working on WP7 and MonoDroid really quickly.

    To be honest, I do at least partly agree with you - PCL code takes longer to write initially and it can leave you thinking "is it worth it?". However, I believe it will pay off hugely in later project maintenance - especially when you get to projects with hundreds of classes. And I'm happy to do more new code, rather than more project maintenance.

    But I do respect that there's personal developer preference and choice involved here!

    Really glad to hear you are making progress with the MS PCL team :) But please don't feel we need "proper implementations" - the way the PCLs currently link to MonoTouch is OK by me - it's just some small bits of the tooling that I'm struggling with (e.g. the way MonoTouch will only link to profile1 projects).

    Thanks again for all the explanations - and I'm really looking forwards to the new tasty bits :)

    Stuart

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai

    I think they're both acceptable approaches. I think they both have their places where they fall down. To be clear, I wasn't advocating file linking over the PCL. just trying to make it clear that it wouldn't do what people expect without a lot of architectural work in many practical situations. Personally, I would like the PCL approach to get to a point where this isn't the case.

    That said, i still think you might be missing something on TaskyPro. The project setup looks like this:

    image

    There's only one core lib project - Tasky.Core. Any changes made there are reflected in the other projects if you're using the project linker. If you're just using manual linking, you'll still need to manually link the file, but in in either case, if you rename a method, or make any other change, it's automatically updated in the other projects.

  • StuartLodgeStuartLodge USBeta ✭✭✭

    Nope - I understood.

    But my experience with the project linker was that it didn't work very well (maybe I should try it again...)

    And when I said rename a method, then I meant using automated refactoring - e.g. using resharper to change the name, change the order or parameters, add a parameter, etc - this works really well with Portable Libraries - but doesn't work using linked files - because Resharper doesn't "understand" the linking.

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai
    edited October 2012

    It should work just fine if you do it in the core project.

  • StuartLodgeStuartLodge USBeta ✭✭✭

    I wasn't advocating file linking over the PCL.

    It is OK if this is your opinion!

    :)

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai
    edited October 2012

    I'm saying, in the context of this thread. I'm not advocating one or the other.

    Now, with that said, if you asked me, which do I recommend, I'd more often than not, point you to file linking.

    But in the context here, whichever people prefer is fine. I just wanted to point out, that in many practical scenarios, without major architectural re-work, it won't have the effect that people expect it to. And I think for those that are reading this thread, thinking that the PCL is magic, they should definitely be aware of this pitfall.

    Additionally, both have their pros and cons:

    PCL is easy and clean, especially if you don't want to target windows phone and use SQLite. However if you do, you begin to do lots of complicated architectural yoga, so that you can pull out a bunch of stuff. However, as pure as that may seem, it actually adds quite a bit of code when a few ifdefs would have sufficed.

    On the other hand, file linking isn't quite as neat. Certainly doesn't feel as good in my programming OCD, but it does solve things rather well, and I don't have to jump through hoops to solve basic platform divergence. However, the file linker isn't perfect either. 1) it's not available in MD, and 2) it doesn't link files that already exist, you have to exclude them from your project and then re-include them (trivial, but still lame) for them to get linked.

    But, if you go this route, you get the best of both worlds, you get a single shared core-lib (which i usually target at .net 4.5 and create a test project for), you get the power of conditional compilation, AND you can still do dependency injection, provider pattern stuff, etc.

    Again though, if your project is simple, or if you prefer to stay architecturally pure, the PCL is totally an option.

  • StuartLodgeStuartLodge USBeta ✭✭✭

    I'm a bit worried I might have sidelined Wally's thread - sorry!

    I agree with you lots. Using C# across all 3 platforms is the key mono strength. To get around the csproj challenge, there are at least a couple of existing approaches, but neither of them are quite perfect. I do disagree on PCL only working if "your project is simple" - but I can't help but agree that right now PCLs are pretty hard to use in MonoTouch - which is where the I started in this thread - "it requires some hideous configuration and csproj hacking to get code working"

    Thanks again for the comments and thoughts - and for the news that new tools and toys are coming - I always like new toys :)

    I'm going give the project linker another go next time I start a new project, but right now I'm going to get back to building code - I might even have a go at building a PCL Sqlite-net at some point :)

    Thanks again

    Stuart

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai

    Awesome. Glad you're using our products, @StuartLodge. And I'm glad you're contributing to the discussions here on the forums.

  • StuartLodgeStuartLodge USBeta ✭✭✭
    edited October 2012

    @bryancostanich Don't want to revive the discussion - think we've talked enough and we both respect each other's preferences. However, I don't know if you are interested, but out of curiosity I had a quick go (2 hours) at refactoring sqlite-net so it doesn't rely on #if statements

    The result is:
    https://gist.github.com/3857333

    Basically:

    • all apps include sqlite3.cs (linked or PCLd)
    • But Android,iOS include PinvokeSqlite3.cs and call PInvokeSQLite3.EnsureInitialised();
    • And Wp7 includes CommunitySqlite3.cs and call CommunitySqlite3.EnsureInitialised();

    This current adapter approach does add some small overhead (but not too much). The resulting code is a bit longer than the #if code.

    I tested it on Android using TaskyPro - seemed to work.

    I tried to test it on WP7 but the emulator doesn't like the tip of TaskyPro - it won't start the app for me with the old or the new SQLite :(

    There was a fair amount of cut and paste and macro work in the conversion, but little real challenge. The only problems I had were:

    • there were some differences in the #if blocks - e.g. public static extern IntPtr ColumnBlob (IntPtr stmt, int index); versus public static byte[] ColumnBlob(Sqlite3.Vdbe stmt, int index)

    • I wasn't sure about the block:

                    #if SILVERLIGHT
                      val = Expression.Lambda(expr).Compile().DynamicInvoke();
                    #else
                      var m = (FieldInfo)mem.Member;
                      var eee = Expression.Lambda (expr);
                      val = m.GetValue(obj);                      
                    #endif
      

    I think given another hour or two I could make TaskyPro use PCLs... might have a go... but right now - I need to do the day job :)

    Stuart

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai

    @StuartLodge - I had @ConceptDev go through this same exercise, I think he still has the code around someplace. Hopefully he can dig it up and post it, or link to it.

    It's definitely possible to do, make no mistake. But the real issue, for us at least, when we were evaluating it, was that it was overly complex. Sure, it was super architecturally clean, but we didn't get a lot of bang for our buck. in fact, in the end, we decided that a few #ifdefs were less work and less hassle.

    we got everything we needed for cheap by simply making a single core project and then linking. it was simple. so that's what we decided to push. simplicity. :)

    anyway, again, to be clear, if you want to go the PCL route, that's entire cool with me, with us. i pushed for PCL support internally. :) i think it's a perfectly valid way to approach it. i'm happy that you're using the platform and that you have these options.

  • CraigDunnCraigDunn USXamarin Team Xamurai

    Hey @StuartLodge, as @bryancostanich was saying, I shoehorned SQLite-Net into a Portable Library Project for a TaskyPro example. I took a slightly different approach where I pushed the API down into an abstract base class, then pass the implementation in from each platform app.

    The complete 3xplat app is on my github as TaskyProPortable.

    Specifically, the abstract class that gets used in the Portable Library is SQLiteBase and then the implementation of SQLite is the same #if defined code you're used to ~ linked into the platform apps and instantiated/passed to the Portable lib. So there is still some linking req'd in this case ~ but only once, it's more like adding a reference. You could flatten the #ifdefs out, but then you're in upgrade hell!

    It is far from ideal, as Bryan says; goals included being able to keep updating SQLite-Net from source so I was trying to do as little as possible to that file. But as you also discovered, to get full cross-platform access to SQLite on iOS, Android, Windows Phone (and now Windows 8/RT) you have to make compromises :)

    I really wanted Portable Libraries to work, and I still don't mind it; but linking does feel simpler and fewer compromises are required in the code (IMHO). I would encourage everyone to understand the advantages & limitations of each then choose what works for them (that's where your posts are helpful :-). Tooling support varies now (and improvements are likely over time) -- either way, it beats the &*$%^# out of writing (and testing) the same stuff in C#, then again in Objective-C _and_ Java!

  • UlrikeUlrike USBeta

    Awesome discussion! @bryancostanich: Do you have any highlights you can share about the upcoming "tasty bits" you allude to? Would help us with planning our code-sharing strategy.

  • BryanCostanichBryanCostanich USMember, Xamarin Team Xamurai

    nope. stay tuned. :)

  • StuartLodgeStuartLodge USBeta ✭✭✭

    Cheers @conceptdev for pointing me at that code. I like the look of the interface approach you've taken for sqlite - I didn't go that way because it was easier to identify the #if's than it was to identify from code than the public API.

    I think I'm going to take that approach and turn it into a portable plugin in vnext - https://github.com/slodge/MvvmCross/tree/vnext/Cirrious/Plugins - thanks :)

    Also thanks to whoever it is who's given https://bugzilla.xamarin.com/show_bug.cgi?id=7173 a kick - if that's resolved then it should remove one of the last remaining practical problems for loading/building PCL2 libraries for MonoTouch.

    This portable topic is definitely IMHO - to me portable feel simpler and has fewer compromises - so we're 180 apart.... but we're all agreed that it's a heck of a lot better going the C# route instead of C#+ObjC+Java!

  • StuartLodgeStuartLodge USBeta ✭✭✭

    @conceptDev - you're bad for my work on my dayjob! I've taken your abstraction approach and turned it into interfaces and a portable plugin - http://slodge.blogspot.co.uk/2012/10/a-sqlite-example-vnext-portable.html - thanks for the code - and for distracting me away from work :)

  • CraigDunnCraigDunn USXamarin Team Xamurai

    @StuartLodge glad I could help ;-) nice work, maybe tomorrow will be more productive (at the dayjob)!?

  • jcmm33jcmm33 GBMember

    One additional point i would like to make surrounding PCLs is increasing 3rd party support/refactoring towards PCLs.

    I'm starting to notice that certain 3rd party OSS libraries are moving towards implementation through PCLs. To date its been quite painful for us to have to download the source for these libraries, adjust to work with monotouch and then move forward. In theory the principle of them moving to a PCL implementation should save us a lot of effort.

    With Nuget 2.1 having PCL support i would suggest that PCLs are going to become more common place.

  • CodeMonkeyCodeMonkey GBMember ✭✭✭

    Not really a code issue but it is driving me mental, why is the command for stepping through code 3 keys? Is there a reason you couldn't use F10/F11? I'm finding traversing my code slow because I can't hover over my code (to get object info) while either clicking the Step through button or using the shortcut.

  • ShaneMunnShaneMunn AUBeta ✭✭

    @codemonkey, I remapped mine to match VS, but I do understand that it would be nice to have a set of key bindings that you can use to match VS. I think the current ones are to match xcode (?), which doesn't really help people who bounce between VS and MD.

  • JonathanPryorJonathanPryor USXamarin Team Xamurai

    It doesn't help those who bounce between Visual Studio and MonoDevelop, but it does conform to "platform conventions," helping those who use more than just MonoDevelop on OS X. For example, OS X conventions include a subset of Emacs shortcut keys: Ctrl+A is beginning-of-line, Ctrl+E is end-of-line, Ctrl+K is "kill-to-end-of-line", etc. MonoDevelop properly supports all of these shortcut keys on OS X, just like XCode, TextEdit, BBEdit, etc.

    Visual Studio, obviously, won't support any of these conventions, and will in fact have "conflicting" shortcuts, e.g. Ctrl+A is select-all, not beginning-of-line.

    For those bouncing between Visual Studio and MonoDevelop, you can change the shortcut keys. Defaults should follow platform conventions, as not all developers will be coming from Visual Studio.

  • CodeMonkeyCodeMonkey GBMember ✭✭✭
    edited October 2012

    Cheers guys, have started updating my shortcuts. The 'END' button has caught me out so many times today, its making me code slower :/. This is my first week on a Mac as well so i'm up against it, not a mac person...

  • Defaults should follow platform conventions, as not all developers will be coming from Visual Studio.

    Agreed. But MonoDevelop could make it easier for Visual Studio users by having a "Visual Studio" mode/macro/whatever that made this and other UI elements more closely track VS.NET.

    Besides keyboard, the following always trip me up:

    • The sort order of the Window menu. I really would like it sorted most recently used first like Visual Studio. MD is ordered by open date.
    • The order of the debugger step over/in/out is different in MD and VS.

    But adding Intellisense support to the Immediate window is my #1 MD request :-).

  • ShaneMunnShaneMunn AUBeta ✭✭

    @jonp Fair point.

    I would like to see a set of key bindings that can be selected in MD rather than just "Default" and "Custom", although really the only ones that I found to cumbersome were the step into / over keys.

  • StuartLodgeStuartLodge USBeta ✭✭✭

    Does anyone have a ready made VS-compatible key-mapping set that can share somehow? While I'm setting up this new dev box, I may as well try to see if I can make it more winded friendly :)

  • StuartLodgeStuartLodge USBeta ✭✭✭

    Just an update on the PCL thing... support is still getting better - https://bugzilla.xamarin.com/show_bug.cgi?id=7173 is now marked as fixed - so hopefully we'll be fully working in a release real soon :)

  • KarlWaclawekKarlWaclawek CAMember

    I know this is an old thread, but I just started Xamarin Development.
    I am trying to use the Project Linker approach, as the PCL approach restricts the supported APIs too much for my taste.

    OK, so I created the MyApp.Core project as a .NET 4.0 class library and then I used VS Project Linker to link it to the MyApp.Android project as a Source project. So far so good. However, it turns out that the Core project requires other libraries I have already written. No problem, I thought, just link them as source projects to MyApp.Andoid as well. But apparently you can only have one source project.

    There must be something here I don't understand, conceptually.

    Any ideas?

  • SajSaj USMember

    I haven't found a project where it builds an IOS app/game and then a tutorial to port it to WP8.

  • BernieHabermeierBernieHabermeier USUniversity ✭✭

    @JonathanPryor‌ You know, Ctrl+K in emacs is "kill-to-end-of-line", but what is killed goes into a buffer that you can later yank back out with Ctrl+Y. A lot of places seem to get this wrong. I don't think this is a personal setting -- I've relied on that for years. It doesn't work in Chrome / Google Apps that way either. Is there a way to "cut-to-end-of-line" instead of "kill-to-end-of-line"? Just wondering. Would like to be able to cut/paste that way if I can.

Sign In or Register to comment.