Friday, 6 February 2015

Using C# dynamic type and NewtonSoft.Json to deserialize JSON

Today I had a requirement to poke a JSON api and capture the response as part of a payment gateway, all from my C# code-behind in a .Net webforms project. Dynamic seemed a good way to go:
                var results = JsonConvert.DeserializeObject(jsonResponseFromApi);
                var oneThingIWant = results.thingYouWant;
                var anotherThingIWant = results.something.somethingDeeper;

Tuesday, 27 January 2015

Deleting svn files and directories, Mac OSX

I recently inherited a project that used to be in svn and is now thankfully in git. Unfortunately all the old svn files were still hanging around. To remove them I did this from the root of the project
find . -name .svn  -type d -print0 |xargs -0 rm -rf

Wednesday, 7 January 2015

Entity Framework - Unable to update EntitySet - it has a DefiningQuery and no element exists to support the current operation.

I had this error when working on an older .Net site yesterday with EF4. It seems that the db table wasn't setup with a primary key which apparently makes EF see it as a view. Looking at the XML in the .edmx file revealed this for my table:

<entityset Name="SpecialFeatures" EntityType="EB.Store.SpecialFeatures" store:Type="Tables" store:Schema="dbo" store:Name="SpecialFeatures">
            <definingquery>SELECT 
      [SpecialFeatures].[Id] AS [Id], 
      [SpecialFeatures].[ProductDetailIcon] AS [ProductDetailIcon], 
      [SpecialFeatures].[SearchResultsIcon] AS [SearchResultsIcon], 
      [SpecialFeatures].[Name] AS [Name]
      FROM [dbo].[SpecialFeatures] AS [SpecialFeatures]
</definingquery>
          </entityset>
To overcome this problem I performed the following surgery on the db and xml:
  1. Add a primary key to the db table in SSMS
  2. Open edmx file in text editor
  3. Locate the entity in the edmx:StorageModels element
  4. Remove the DefiningQuery entirely
  5. Rename the store:Schema="dbo" to Schema="dbo"
  6. Remove the store:Name property

Tuesday, 23 December 2014

Checking entitlements of iOS app bundle using codesign

I had a problem arise today - it became clear that a production iOS app wasn't requesting push notification permission from users. I went through some tagged releases and tested locally with Xcode, repeatedly installing and uninstalling and changing the date on my phone, and every time I was correctly asked for push permissions when expected.

So my attention turned to the production app and its permissions/entitlements. There was clearly nothing wrong with the code, but perhaps it hadn't been signed properly?

In Xcode's Organizer there is no way (as far as I can tell) to recover the ipa file that was submitted to Apple using the 'Submit' button, so instead I went to the App Store on my mac and downloaded the live production app. In Finder, I changed the .ipa file to a .zip, and opened up the package contents. In the 'payload' directory is the app file. With this, I checked the entitlements like so:
codesign -d --entitlements :- "Payload/YourApp.app"
The response showed that there were no APS entitlements. I compared it to a known working .app file, and the following entry was missing:
<key>aps-environment</key>
It seems that at some point the app was submitted with the wrong Distribution Profile. If it only it wasn't Christmas holidays at iTuneConnect!

Friday, 19 December 2014

Xamarin Android back button event during ActionMode

When a user presses the back button during an ActionMode, OnBackPressed() doesn't get called, s0 how to do we intercept this event if we need to do something?

Like this:
 public override bool DispatchKeyEvent(KeyEvent keyevent)
        {
            if (_contextualActionBar != null && ItemsInEditMode.Any())
            {
                if (keyevent.KeyCode == KeyEvent.KeyCodeFromString("KEYCODE_BACK") && keyevent.Action == KeyEventActions.Up)
                {
                    DeselectallItems(_listOfItems);
                    KillActionBar();
                    return true;
                }
            }
            return base.DispatchKeyEvent(keyevent);
        }