Announcing Realm for Xamarin

AndyDentAndyDent AUMember ✭✭

I'm very happy to say that we've just made the Xamarin version of the Realm mobile database engine publicly available after a few months in private beta. Read the launch blog post for more details. We have a Xamarin Component in approval and you can just install with NuGet (package named Realm).

I'm very happy to answer any deep technical questions as I've been one of the team on this for about 10 months. Apart from giving Xamarin users access to a great product, we have learned a lot about implementing LINQ, using the Fody weaver to generate code and interfacing to C++.

You can use Realm either from PCL or directly in native code.

«1

Posts

  • stvansolanostvansolano UMInsider, University ✭✭✭

    Interesting, thanks for sharing @AndyDent!

    So is that really free? I'm curious about been introduced for free as part of the pricing page. Would be free forever? Any plans further enterprise features?

  • AndyDentAndyDent AUMember ✭✭

    Yes it is definitely free forever. There are additional services and future enterprise products that may or may not have frree components, see our pricing page.

  • BenBishopBenBishop USBeta ✭✭

    I'm really excited to use this on a client project. I've used (fought) Sql.net in the past and have lately just been serializing models to JSON files.

    I'm also doing a Brax video series on it as I get up to speed on it (much like I did with the XAML Previewer and DataPages):
    https://brax.tv/series/master-your-xamarin-realm-db/

  • tomnuentomnuen VNMember ✭✭

    It failed to build on device (Simulator is fine). Error: could not AOT assembly.

  • AndyDentAndyDent AUMember ✭✭

    Please log an issue and tell us more about your setup and any error messages you can see.

    Typically, failure to build is more of a problem with the Xamarin tooling than due to Realm.

  • AndyDentAndyDent AUMember ✭✭

    @tomnuen how are you going with your build? Do you have non-English characters in your root folder?

    Xamarin has a problem with such a path, discussed in the forums and already experienced by a Japanese user - in issue 540

  • TomNuen.3170TomNuen.3170 AUMember

    @AndyDent I got this error when I tried to build for iPhone 5S device. If I removed references to Realm.dll, it builds fine.

    MTOUCH: error MT5209: Native linking error: file is universal (4 slices) but does not contain a(n) armv7s slice: /Users/tomnuen/Applications/.../obj/iPhone/Release/mtouch-cache/libwrappers.a file '/Users/tomnuen/Applications/.../obj/iPhone/Release/mtouch-cache/libwrappers.a' for architecture armv7s

  • AndyDentAndyDent AUMember ✭✭

    @TomNuen.3170 you're absolutely right. When we build for Xamarin we're not including LinkTarget.Armv7s. I have added issue 553 and we should get it fixed in the next release.

    In the short-term, you can work around it by going into the Project Options for your application project, that targets IOS.

    Under Build - IOS Build, set the Platform: popup menu to iPhone

    You can then change the Supported architectures: to just armV7 + ARM64

  • tomnuentomnuen VNMember ✭✭

    @AndyDent Thank you for getting at the bottom of this so quickly. Yes, I changed to armV7 + ARM64 and it built successfully! Ready to test drive Realm now, it looks really promising.

  • AndyDentAndyDent AUMember ✭✭

    There's a great article on Cocoanetics from 2014 about Apple dropping it by default in XCode 6. Bottom line - as a library vendor we should support your choice to still include the architecture, which is why I just put a PR in which fixes it.

  • MarcoTMarcoT USMember ✭✭

    Hi @AndyDent ,

    I know that this is not the best place to ask this question, but I try it anyway.
    I've read about Realm and I wanted to do a small test to see if we should switch to this o continue with Sqlite.

    I download from our server a list of breed and i want to copy inside my local db:

    foreach (var breed in listofbreed)
                    {
                        realm.Write(() =>
                        {
                            var b = realm.CreateObject<DbModel.RealmBreeds>();
                            b = breed;
                        });
                    }
    

    if I do this, after the foreach I have in my local db a list of empty objects.

    Instead if I write:

    foreach (var breed in listofbreed)
                    {
                        realm.Write(() =>
                        {
                            var b = realm.CreateObject<DbModel.RealmBreeds>();
                            b.id = breed.id;
                            b.name = breed.name;
                        });
                    }
    

    it works.

    Of course I don't want to write every property of our objects. Do you know how can I do?

    Ps. Realm seems very good and has some features really nice, but I need to solve this problem before I can switch to Realm.

    Thanks,
    Marco

  • AndyDentAndyDent AUMember ✭✭

    @MarcoT we're looking at a couple of ways of making that kind of scenario easier.

    For now, I"m not sure entirely where your objects are coming from but you can create a simple RealmObject and then move it into the Realm using Manage. This has some limitations with related objects.

    given a class:

        public class RealmBreed : RealmObject
        {
            public int id;
            public string name;
        } 
    

    say for some reason they had to be created outside of the Realm:

            var listofbreed = new List<RealmBreed>();
            for (int i = 0; i < 10; i++) {
                listofbreed.Add( new RealmBreed {id=i, name=$"Name{i}"} );
            }
    

    they can be moved into the Realm:

            using (var realm = Realm.GetInstance ()) {
                foreach (var breed in listofbreed) {
                    realm.Write (() => {
                        realm.Manage(breed);  // you could also put the entire foreach in here as one transaction
                    });
                };
                var numInRealm = realm.All<RealmBreed> ().Count ();
                System.Diagnostics.Debug.Assert (numInRealm == 10);
            }
    
  • MarcoTMarcoT USMember ✭✭
    edited June 2016

    Hi @AndyDent,

    thank you for your reply, it works.

    Can I ask if Realm supports also windows phone and all the other window platforms supproted by Xamarin?

    Thank you,

    Marco

  • TimKellyTimKelly USMember

    Hi @AndyDent ,

    I'm a Xamarin Forms youngster, and have just added Realm to my PCL project (for iOS and Android). I've added Realm through NuGet to my PCL project and to both the iOS and Android projects.

    Everything works great for the Android build, I can use Realm to store username for the app. But when I build for iOS, I get:

    "The PCL build of Realm is being linked which probably means you need to use NuGet or otherwise link a platform-specific Realm.dll to your main application."

    I've reaAndroid.

    Any suggestions?

    Tim

  • AndyDentAndyDent AUMember ✭✭

    That error means it didn't add the IOS NuGet for some reason. Maybe doing two at once?

    Check and see if it is there, see if removing and re-adding to the IOS Project makes a diifference. Otherwise can dig out details on how to manually add by editing csproj.

  • TimKellyTimKelly USMember

    Cheers Andy.

    The package was there in iOS. I removed all references to Realm, Fody and DotNetCross.Memory.Unsafe from the the whole solution and re-added - with exactly the same result.

    I tried editing the iOS.csproj from:

    <Reference Include="Realm">
      <HintPath>..\packages\Realm.0.76.1\lib\portable-net45+sl5+wp8+wpa81+win8+monoandroid+Xamarin.iOS10+monotouch+Xamarin.Mac\Realm.dll</HintPath>
    </Reference>
    
    ... to ...
    
    <Reference Include="Realm">
      <HintPath>..\packages\Realm.0.76.1\lib\Xamarin.iOS10\Realm.dll</HintPath>
    </Reference>
    

    ... as this was similar to how the android.csproj referenced Realm. - but when I do this, I get the error:

    Error MT0034: Cannot reference 'Xamarin.iOS.dll' in a MonoTouch project - it is implicitly referenced by 'Realm, Version=0.76.1.0, Culture=neutral, PublicKeyToken=null'. (MT0034)

    I'd love to use Realm as it seems so easy (when it's working as in Android).

    Any further help would be appreciated.

    Cheers,
    Tim

  • AndyDentAndyDent AUMember ✭✭

    Hi @TimKelly

    Just to double-check, I just created a new Xamarin multi-target (native IOS and Android) solution from scratch.

    I then added the public Realm 0.76.0 NuGet.

    The IOS project contains:

        <Reference Include="Realm">
          <HintPath>..\packages\Realm.0.76.1\lib\Xamarin.iOS10\Realm.dll</HintPath>
        </Reference>
    

    That confirms you worked out exactly the right content for what should have been installed by Fody.

    I did a bit more research on your error - did you compile sucessfully with Xamarin Forms before adding Realm?

    How did you create the solution?

    Looking at this posting it seems your IOS project for some reason is still an old MonoTouch project, instead of being migrated to Xamarin.IOS.

    We do not support the old MonoTouch projects and that would explain why NuGet didn't automatically add the Realm links to your project.

    See https://developer.xamarin.com/guides/cross-platform/macios/unified/updating-xamarin-forms-apps/

  • AndyDentAndyDent AUMember ✭✭

    @TimKelly can you please send a copy of your project, at least a stripped-down version, to [email protected] so we can try to add detection of this situation into our NuGet install process?

  • TimKellyTimKelly USMember

    Hey Andy,

    Yep, thanks for your help. I have now migrated to Xamarin.IOS. I had to do this manually, but that's fine. I also had to add in the reference:

    <Reference Include="Realm">
      <HintPath>..\packages\Realm.0.76.1\lib\Xamarin.iOS10\Realm.dll</HintPath>
    </Reference>
    

    ... as it wasn't there at all after I removed and readded Realm to all my projects.

    All fine, but now I have this error:

    Default constructor not found for type YDFMobileApp.RealmDB+RealmHelper
    

    After searching for a solution, I found that I can get around this by setting my Linker Behaviour to 'Framework SDKs only'.

    Unfortunately, there are other unrelated aspects of my project that require this to be set to 'Link All'.

    Do you have any other suggestions to get around my current error? BTW, I do have a constructor for that class...although I'm not sure what the reference to +RealmHelper is.

    Cheers,
    Tim

  • TimKellyTimKelly USMember

    ...I've just got around this issue also. I added an XML file with a directive for the linker not to ignore my class.

    Thank you for your help.

    Tim

  • TimKellyTimKelly USMember
    edited July 2016

    Hi again Andy,

    After successfully using Realm in my project for the last week, for no apparent reason, Realm has stopped my project building, giving me an error with Fody described below:

    Error: Fody: An unhandled exception occurred:
    Exception:
    Value cannot be null.
    Parameter name: type
    StackTrace:
    at Mono.Cecil.ModuleDefinition.ImportReference (Mono.Cecil.TypeReference type,
    IGenericParameterProvider context) ...... in filename unknown ...
    at ModuleWeaver.ExecuteWeavers () ...... in filename unknown ...
    at ModuleWeaver.Execute () ...... in filename unknown ...
    Source:
    Mono.Cecil
    TargetSite:
    Mono.Cecil.TypeReference ImportReference(Mono.Cecil.TypeReference,
    Mono.Cecil.IGenericParamaterProvider)

    I have tried removing and re-adding Realm and Fody, but cannot get rid of this error. Are you able to help me diagnose this problem?

    Cheers,
    Tim

  • AndyDentAndyDent AUMember ✭✭

    We are very sorry - 0.77.0 was inadvertently released with a bug preventing compilation of PCL projects. That was a failure in our release process in that a fix was tried for the weaving problems which only fixed them in a limited environment. Our first priority is fixing the issue and getting 0.77.1 out the door ASAP.

  • TimKellyTimKelly USMember

    That would explain it :-) ... So I'm in a situation where I need a solution this week. Is it possible that there will be a patch by tomorrow or Wednesday? Or is it possible that I can build with the previous version before 0.77.0 ?

    Cheers,
    Tim

  • AndyDentAndyDent AUMember ✭✭

    To go back to an older version of Realm (or any NuGet installation):

    1. Delete the Realm.0.77.0 directory in Packages, which is usually at the top level of your solution directory
    2. edit the Packages.config file in each project directory and change the Realm version back to 0.76.1
    3. in Xamarin Studio, right-click your Packages folders in each project and choose Restore
  • AndyDentAndyDent AUMember ✭✭

    @TimKelly said:
    Is it possible that there will be a patch by tomorrow or Wednesday?

    This is currently our top priority but involves some wrestling with Fody.

    For anyone picking up this thread, it only affects using Realm with PCL projects.

  • mattwardmattward GBMember Xamurai

    @AndyDent - Editing the packages.config file and restoring will not fix the HintPaths for the references in the project. To find an older version of a NuGet package you can run a package version search in the Add Packages dialog:

    Realm version:*
    

    The above search will return all versions of the Realm NuGet package. Then install the version you need in the normal way.

  • TimKellyTimKelly USMember

    Andy and Matt, I thank you both. I'm back up and running with 0.76.1

  • TimKellyTimKelly USMember

    Hi Andy,

    I notice that Realm has been updated to 77.1 . Do you know if this has addressed the bug stopping PCL projects from building?

    Cheers,
    Tim

  • AndyDentAndyDent AUMember ✭✭

    @TimKelly Yes 0.77.1 fixed the PCL build bug.

    We had an interesting new bug surface between 0.76.1 and 0.77.1 which uncovered some user behaviours we were not anticipating - people creating Realm instances in nested screens and returning RealmObjects that lived longer than the Realm instance. This has affected less than 1% of users and a fix is currently being reviewed.

  • siuitsiuit VNMember
    edited November 2016

    Hi @AndyDent
    Build code : var realm = Realm.GetInstance(); has error "The PCL build of Realm is being linked which probably means you need to use NuGet or otherwise link a platform-specific Realm.dll to your main application." Help me, pls!

  • AndyDentAndyDent AUMember ✭✭

    I assume you have one or more PCL projects and an iOS or Android project. You need to add the NuGet to those platform projects too.

    This is not Realm-specific, it happens for any package which includes native code. The PCL library acts as an interface definition but the work is done by the platform-specific libraries which NuGet links. It's sometimes referred to as the bait-and-switch pattern.

  • siuitsiuit VNMember
    edited November 2016

    Hi @AndyDent
    I installed Realm to Portable project and Android project, But stilling has error.
    I'm using Xamarin Hybrid webview app, This is my project: https://drive.google.com/file/d/0B27T3QXt-RMrY3ZxZWVCdzMzR3M/view?usp=sharing
    Help me, please! This project is very important.

  • AndyDentAndyDent AUMember ✭✭

    Fixed!

    @siuit I reproduced it and also verified that it appears you have included the nuget in the platform build.

    Something very weird has happened - when I looked at JTMobileAndroid.csproj it had a hint path pointing to the PCL version of Realm.dll

      <Reference Include="Realm, Version=0.76.1.0, Culture=neutral, processorArchitecture=MSIL">
        <HintPath>..\packages\Realm.0.76.1\lib\MonoAndroid44\Realm.dll</HintPath>
    <!-- bad path in original      <HintPath>..\packages\Realm.0.76.1\lib\portable-net45+sl5+wp8+wpa81+win8+monoandroid+Xamarin.iOS10+monotouch+Xamarin.Mac\Realm.dll</HintPath>  -->
        <Private>True</Private>
    </Reference>
    

    Simply changing the hint path as shown above enabled the app to build and run.

    Note that I also disabled armeabi in the JTMobileAndroid Options - Build - Android Build - Advanced tab as we do not support that ABI (missing instructions in the compilers, unfortunately, but it represents a very old, tiny subset of devices).

  • siuitsiuit VNMember

    Hi @AndyDent , Thanks a lot

  • siuitsiuit VNMember

    Hi @AndyDent
    I has a database realm file (mydatabase.realm), i want to connect to This project, but project only create default.realm and use it. Help me!

  • AndyDentAndyDent AUMember ✭✭

    @siut you can simply pass in a path to myRealm = GetInstance("mydatabase.realm");

    See the GetInstance API doc

    If you want to control more aspects of your Realm, you create a RealmConfiguration which can also take a partial database path, and pass that to GetInstance.

    See the docs, for example, on just putting a few classes in a given Realm.

  • siuitsiuit VNMember
    edited November 2016

    @AndyDent , thank you so much
    Connected to my database realm file (mydatabase.realm)
    But I dont know how to add data to local database file which is in my project, i tried to use:
    var config = new RealmConfiguration("/data/data/JTMobileAndroid.JTMobileAndroid/files/App_Data/mydatabase.realm");
    var realm = Realm.GetInstance(config);
    realm.Write(() =>
    {
    for (int i = 1; i < 54; i++)
    {
    var d = realm.CreateObject();
    d.ImageID = i;
    }
    });

    But Run the 2nd, database realm file dont has new objects.
    How to save database file in mobile device.
    This is my project.
    https://drive.google.com/file/d/0B2Fa7fFSbAFPS2xVemstX0RyaEE/view?usp=sharing
    Help me, pls!!!

  • batmacibatmaci DEMember ✭✭✭✭✭
    If I use pcl Version, does it also work for uwp apps?
  • AndyDentAndyDent AUMember ✭✭

    @siuit you don't need to specify a full path and that's normally discouraged. Your response made me think the docs for GetInstance could emphasise that point more fully.

    The default location is in the document area for your app so just a filename willl normally do.

    I am very surprised, however, that this appears to work the first time and then fails to work the second.

    Thanks for the full sample, I have been testing it and confirmed that using the full pathname does fail to save.

    Accordingly, I have logged issue 943.

    The good news for you is that just using a filename does work -

    var config = new RealmConfiguration("mydatabase.realm");
    var realm = Realm.GetInstance(config);

  • AndyDentAndyDent AUMember ✭✭

    @siuit sorry the above reply looked like it was sent when I wrote it immediately after your post. It was only on returning to the forum today I saw it was actually sitting as a draft.

    @batmaci >If I use pcl Version, does it also work for uwp apps?

    No. Like many components, Realm has a native library. That means that the PCL version is just a set of declarations, replaced at link time by the code which uses the native library.

    The good news is that we are getting very close to having a UWP NuGet you can use, depending on platforms. Initially we are targeting Windows desktop and UWP on Windows 10 phones.

    The core library support for UWP was merged a few days ago.

    That library is now merged into our master build so you can build from source.

    We need to finish up some documentation, samples and explore what cracks need filling for specific configurations but the basics are there.

Sign In or Register to comment.