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);
        }

Thursday, 18 December 2014

Screenshot complete listview in Xamarin Android

Today I needed to turn a complete listview into an image, including the below-the-fold content that was yet to be rendered. I found some Java code on SO and ported it to C#. It works a treat:
public static Bitmap GetWholeListViewItemsToBitmap(ListView listview, HistoryAdapter adapter)
        {

            int itemscount = adapter.Count;
            int allitemsheight = 0;
            var bmps = new List();

            for (int i = 0; i < itemscount; i++)
            {

                View childView = adapter.GetView(i, null, listview);
                childView.Measure(View.MeasureSpec.MakeMeasureSpec(listview.Width, MeasureSpecMode.Exactly),
                        View.MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified));

                childView.Layout(0, 0, childView.MeasuredWidth, childView.MeasuredHeight);
                childView.DrawingCacheEnabled = true;
                childView.BuildDrawingCache();
                bmps.Add(childView.GetDrawingCache(true));
                allitemsheight += childView.MeasuredHeight;
            }

            Bitmap bigbitmap = Bitmap.CreateBitmap(listview.MeasuredWidth, allitemsheight, Bitmap.Config.Argb8888);
            Canvas bigcanvas = new Canvas(bigbitmap);

            Paint paint = new Paint();
            int iHeight = 0;

            for (int i = 0; i < bmps.Count; i++)
            {
                Bitmap bmp = bmps[i];
                bigcanvas.DrawBitmap(bmp, 0, iHeight, paint);
                iHeight += bmp.Height;

                bmp.Recycle();
            }

            return bigbitmap;
        }

Tuesday, 16 December 2014

Intent.FLAG_ACTIVITY_NEW_TASK in Xamarin C# Android

While trying to StartActivity from a list adapter I got this warning:
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
The way to overcome this in Java:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
The not-so-well-documented way to acheive this using Xamarin:
intent.SetFlags(ActivityFlags.NewTask);