I’ve recently been working on a Xamarin.Forms project for Android and iOS and recently came across an issue that took some experimenting to get fixed so I thought I would share it for anyone else that might run into it.

Realm is a database designed for mobile applications and offers a safe, easy, non-ORM replacement for SQLite. The intent is that you can, for the most part, mark your data model objects as RealmObjects and Realm will handle all of the persistence for you. As with anything, it gets more complicated than that but so far it’s still much better for what I’m doing than SQLite. If I needed the ability to do offline synchronization with an online data source, I’d be looking at Azure Mobile Apps , but as I don’t I’m fine with what Realm will do for me.

Adding Realm to your Xamarin.Forms application just requires adding the Realm NuGet package to your projects. From there, you should be able to compile your projects without any issues.

However, if you have Continuous Integration set up to auto-build your projects and run tests with every build, it’s possible to run into an issue. I use Visual Studio Team Services to build all of my mobile projects and then deliver them to HockeyApp for beta testing. I’ll have to post more about setting up the Build Definition (the steps for building and uploading my compiled applications) but want to focus on the issue that having Realm in your projects has with the build process.

When you add Realm to your projects, it adds a Target as part of the package.
That step, called CopyRealmWeaver which copies RealmWeaver.Fody.dll as part of the build process. I won’t get into what Fody is but it’s a necessary part of using Realm. The XML found in the Realm.targets has the following inside of it:

<Target Name="CopyRealmWeaver" BeforeTargets="FodyTarget">
  <Message Text="CopyRealmWeaver" />
  <Error 
    Text="Solution directory was not set. If you are building via xbuild, specify by adding a /p:SolutionDir=/path/to/solution/folder argument. See github.com/realm/realm-dotnet/issues/656"
    Condition="'$(SolutionDir)' == ''" />
  <Copy SourceFiles="$(MSBuildThisFileDirectory)../tools/RealmWeaver.Fody.dll" DestinationFolder="$(SolutionDir)/Tools" />
</Target>

What this does is check to make sure $(SolutionDir) has been specified as part of the call to xbuild, or in the case of VSTS, msbuild. Provided that value has been specified, it then copies the RealmWeaver.Fody.dll from a tools directory in the packages folder into the Solution directory.

What’s wrong here

The problem here is that when compiling with VSTS, there is some step that changes the SolutionDir value to *undefined*. When I ran into this, it was especially weird as I couldn’t seem to find a reference to VSTS, build, and *undefined* anywhere. I did find a Stack Overflow post about Visual Studio replacing $(SolutionDir) with *undefined* which wasn’t the solution to my problem exactly but did get me on the right path. From there, I took a look at the call to MSBuild to see what was showing up:

2016-12-13T19:23:38.1392477Z ##[command]"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe" "C:\a\1\s\src\Droid\MyApp.Android.csproj" /nologo /nr:false /dl:CentralLogger,"C:\a\_tasks\XamarinAndroid_27edd013-36fd-43aa-96a3-7d73e1e35285\1.1.1\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll";"RootDetailId=39592de0-fb1c-4156-a73e-b2e8ee77129e|SolutionDir=C:\a\1\s\src\Droid"*ForwardingLogger,"C:\a\_tasks\XamarinAndroid_27edd013-36fd-43aa-96a3-7d73e1e35285\1.1.1\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll"  /p:configuration="Release" /p:_MSDeployUserAgent="VSTS_db204fe6-401b-4488-b9c9-02229bdeafd2_build_25_317" /t:PackageForAndroid /p:OutputPath="C:\a\1\b/Release" /p:JavaSdkDirectory=" C:\Program Files (x86)\Java\jdk1.8.0_102"

What I want to highlight from that call to msbuild is SolutionDir=C:\a\1\s\src\Droid. It seems like we’re specifying a Solution Directory, but the error shows us that somehow, that is being overwritten. So we need to override that overwrite and ensure a value is in fact being passed in.

Build Xamarin Additional Arguments

Thankfully, the Build Xamarin project build step has a spot for Additional Arguments at the bottom. In this case, I set the solution directory to the directory of my overall solution file and where the tools directory containing the RealmWeaver.Fody.dll is at. The format of the argument is important so this is what you should be using (adjusting the path for your) tools folder location of course:

/p:SolutionDir=”src”

With that done, I was able to run builds without any issue. This seem to be an Android only issue so you shouldn’t need to change anything on your iOS build.

edit

Last week, on Friday, August 26th, I lost a very important person to cancer. I’ve been having a particularly hard time with this so I thought writing something down might be helpful.

Amy was a person that, for some, it might be hard to grasp the importance of. On top of having three daughters of her own, she was also an adopted or second mother to many people, myself included. I didn’t meet her until I was nearly 20, so I didn’t grow up as a child with her. That didn’t prevent her from becoming not only like a second mother, but also a best friend. I met Amy through my best friend, that I went to highschool and college with, that lived across the street from her (one of the other adopted kids) and what started as me going over to their house occasionally when I was hanging out with him turned into me just going over to hang out with Amy and her family at times. Dinners at their house were frequent. Trips up to their cottage during the summer were equally frequent and amazingly fun. The Christmas Eve get-together at their house was something I never wanted to miss. I can easily say that there were several years I was with their family more than my own. And I was close with the rest of the family as well. I was the same year at the same high school as the middle daugher and only years apart from the older and younger ones.

That did a poor job trying to explain the signifigance this family and this woman had in my life. But until I find better words, it will have to do. A month ago, when I was on a work trip to Boston, Amy texted me about an issue she was having with Facebook on her phone. As I often am for people, I was Amy’s tech support. Much less needed recently but there were years where I was the guy when it came to switching out the ink cartridges for Amy’s printer. I called her and spoke with her for maybe 10 minutes. She said she’d quit smoking a month ago, which was amazing, but that she’d been having difficulty breathing and chest pain recently and that the doctor’s weren’t sure what was causing it. They’d also found a mass in one of her lungs but hadn’t been able to complete a biospy yet due to some issue with her blood work. I could tell she was upset when she was speaking and the issues with her breathing were noticable even on the phone. I helped Amy with her Facebook issue, told her I hoped she’d get better soon, and let her know I’d be in town in October so I’d see her then. I also promised to follow up in a few days. I texted and called my best friend who I knew would be able to give me all the specific details of what was going on. He confirmed most of what she said and said once they’d gotten some results back and knew what was up, he’d let me know.

Ten days later, I got the text message from one of the daughter’s saying that Amy had Stage 4 Large Cell Lung Cancer. She wasn’t stable and was on breathing machines. Days later she was air lifted from the smaller hospital she was in to the Univeristy of Michigan hospital (a vast improvement in care I’m sure). They had to air lift her from ICU to ICU becuase she wasn’t stable enough for anything else. She made it for about ten more days and then passed. I cried. I cried a lot. I cried because I couldn’t belive that she’d gone so fast. I cried becuase I’d never see her again. I cried becuase it hurt that she was gone. I cried becuase I’d never get another call asking me to change her printer cartridges. My wife had a hard time of it too. I left work shortly after I heard, picked her up, and we just went home, sat on the couch, and cried some more. Dealing with my own pain was hard. I couldn’t imagine what it felt like for her daughters or her husband. On the one hand, I’m sure they were happy she wasn’t suffering. But, I’m sure it was more anger and frustration of the time with her that had been stolen from them. From all of us.

The next morning, my wife and I booked travel back to Michigan. Hours later, we found out that Amy’s mother-in-law, her husband’s mother, and the girls’ grandmother, passed away also from cancer. I’d recently found out that she’d been sick for a while and that it was expected, but no one expects something like this. Two generations, gone in two days. I wasn’t around them enough to grow very close to the grandparents but I couldn’t comprehend this actually happening. I couldn’t even begin to grasp the pain the rest of the family must be feeling. Even knowing it was coming doesn’t seem to make it bearable.

At the viewing (a double viewing becuase what’s more messed up than a double funeral), they did an hour where people could share memories of Amy. Many people spoke. Of those that did, quiet a few of them were from people my age or within a few years. Every single one spoke to how sweet Amy was, how kind and considerate, how she’d been like their mother. I didn’t think I’d be able to speak, didn’t know what to say if I did. Suddenly my wife decided she was going to say something. She told a story about how, after moving to Michigan where she only knew me, Amy took her in as one of her own. It was really touching to remember how quickly Amy became her friend and went out of her way for my wife. That’s just what Amy did. After Erin spoke, I decided I should too. The only reason I was able to get up was that I thought of a funny story about Amy that I could share. If I’ve realized one thing from this, it is that making jokes (sometimes funny and sometimes just stupid) is one of the ways I try to deal with things like this. I don’t consider myself a funny person but I did tell a story that made those in attendence laugh and I guess that was good enough. I’d like to think Amy would have liked it.

I wish that after I moved away from Michigan, I made more of an effort to make phone calls or send more text messages to Amy. I wish I’d cherished that friendship as much as I should have. I wish I’d realized just how fast my friend could be gone. I know that in the weeks to come, it’s going to be a lot of realizations of things I’ll never get to do with Amy again and that is sad. However, I know the last thing Amy would want is for us all to stay sad forever. I’ll always hold her in my heart and hope that her ability to be kind to anyone and everyone has rubbed a bit off on me and everyone else.