Author: Sam Storino

Hi, I'm Sam. I'm a programmer and a DIYer. When I'm not finding things to build I enjoy cooking, hiking, camping and traveling the world with my best friend. Say Hello!
How to Create a Many-to-Many Relationship in Realm JS React Native

How to Create a Many-to-Many Relationship in Realm JS React Native

While building my app ThinkBack I decided to use Realm as my underlying data-store. ThinkBack allows users capture notes and categorize them using hashtags. A note can have many hashtags and a hashtag can have many notes. This is the basis of a many-to-many relationship.

Realm’s documentation on model relationships shows an example using a car and manufacturer model. In their example a car has a relationship with a manufacturer, and a manufacturer has a one-to-many relationship with a car. This example creates a “to-many” relationship from manufacturer to car simply by adding a property to the manufacturer model that references a collection of cars.

By default a relationship is one-sided, for example a manufacturer has a link to cars, but cars don’t link back to the manufacturer. In order for a car to know its manufacturer Realm leverages the concept of an inverse relationship. An inverse relationship is simply a link from one object back to another, and is defined by setting the “type” of the linking property as a linkingObjects. This relationship must be explicitly defined otherwise a car will be ignorant to the fact it belongs to a manufacturer. The downside to this is that if you want to load the manufacturer associated with a car you need to issue a separate query in Realm rather than simply dot-notationining into it (e.g. myCar.manufacturer.name)

Below is the example from the documentation. Line 11 defines the “to-many” relationship from manufacturer to car, and line 27-31 define the inverse relationship from car back to manufacturer.

class ManufacturerInverse extends Realm.Object {
  _id!: BSON.ObjectId;
  name!: string;
  cars!: Realm.List<CarInverse>;
  static schema: Realm.ObjectSchema = {
    name: 'ManufacturerInverse',
    properties: {
      _id: 'objectId',
      name: 'string',
      // A manufacturer's related CarInverse objects
      cars: 'CarInverse[]',
    },
  };
}
class CarInverse extends Realm.Object {
  _id!: BSON.ObjectId;
  model!: string;
  manufacturer!: Realm.List<ManufacturerInverse>;
  miles?: number;
  static schema: Realm.ObjectSchema = {
    name: 'CarInverse',
    properties: {
      _id: 'objectId',
      model: 'string',
      miles: 'int?',
      // A car's related ManufacturerInverse objects
      manufacturer: {
        type: 'linkingObjects',
        objectType: 'ManufacturerInverse',
        property: 'cars',
      },
    },
  };
}

Creating a many-to-many relationship between Hashtag and Note

Creating a many-to-many relationship between Hashtags and Notes is exactly the same as the relationship between Cars and Manufacturers.

Note Model

Line 30 defines a “to-many” relationship between a Note and Hashtag. This is equivalent to the manufacturer-to-car relationship in the example above. When a note is queried in Realm the hashtags object will point to N number of hashtags that reference this note. This is handy if you want to load all hashtags for a given note without issuing a separate query (e.g. myNote.hashtags.forEach(...)).

import uuid from 'react-native-uuid';
import Hashtag from './Hashtag';

export interface NoteProps {
  id?: string;
  content: string;
  hashtags: Hashtag[];
}

export default class Note {
  public id: string;
  public content: string;
  public hashtags: Hashtag[];

  constructor({
    id = uuid.v4().toString(),
    content,
    hashtags,
  }: NoteProps) {
    this.id = id;
    this.content = content;
    this.hashtags = hashtags;
  }

  static schema: Realm.ObjectSchema = {
    name: 'Note',
    properties: {
      id: 'string',
      content: 'string',
      hashtags: `Hashtag[]`,
    },
    primaryKey: 'id',
  };
}

Hashtag Model

Line 26 defines a linking object property notes which links back to the hashtags property of the Notes model. This inverse relationship effectively creates a collection of notes that have a reference to this particular hashtag. When a hashtag is queried in Realm the notes object will point to N number of notes that reference this hashtag. This is handy if you want to load all notes for a given hashtag without issuing a separate query (e.g. myHashtag.notes.forEach(...)).

import uuid from 'react-native-uuid';
import Note from './Note';

interface HashtagProps {
  id?: string;
  name: string;
}

export default class Hashtag {
  public id: string;
  public name: string;
  public notes: Note[];

  constructor({ id = uuid.v4().toString(), name }: HashtagProps) {
    this.id = id;
    this.name = name;
    this.notes = [];
  }

  static schema: Realm.ObjectSchema = {
    name: 'Hashtag',
    properties: {
      id: 'string',
      name: 'string',
      // all notes who have this hashtag added in the "hashtags" property.
      notes: { type: 'linkingObjects', objectType: 'Note', property: 'hashtags' },
    },
    primaryKey: 'id',
  };
}

With this relationship in place you can now load a note or a hashtag and have a direct reference to the other side of the relationship:

const note = realm.objectForPrimaryKey<Note>('Note', id);

// load all hashtags associated with the given note and extract their names.
const hashtagNames = note.hashtags.map(h => h.name)
How to Paginate Query Results in React Native with Realm JS (MongoDB)

How to Paginate Query Results in React Native with Realm JS (MongoDB)

While building my app ThinkBack I decided to use Realm as my underlying data-store. ThinkBack’s home screen contains a list of notes which need pagination to avoid loading everything unnecessarily.

From the Realm docs:

Pagination & Limits

Some queries only need to access a subset of all objects that match the query. Realm’s lazy-loaded collections only fetch objects when you actually access them, so you do not need any special mechanism to limit query results.

For example, if you only want to find 10 matching objects at a time (such as in a paged product catalog) you can just access ten elements of the results collection. To advance to the next page, access the next ten elements of the results collection starting at the index immediately following the last element of the previous page.

Lazy-loading removes the need to build paging logic into the query itself and instead defers pagination or limiting results to when you interact with the result set. In other words, paging is handled at the time you want to access/materialize the objects into memory rather than the time you issue a query to Realm.

This post aims to demonstrate this concept through a simplified implementation.

End to End Paging Implementation

The following implementation will load a series of “notes” from Realm, apply pagination logic and present the results in a FlatList to the user. I tend to prefer a layer of abstraction between the UI and the underlying data store, this keeps a clean separation between the front-end and any business logic that may exist.

To support this we’ll create the following:

  • RealmStore.ts, which creates an instance of the Realm datastore.
  • Note.ts, which defines the schema of the Note table in Realm.
  • NoteService.ts, which will contain logic for querying Realm and paginating the results.
  • App.tsx, which will store paging “state” (i.e. what page we’re on, page size), interact with the NoteService class to load paged notes and present them in a FlatList.

The structure of these files in the project is as follows:

root/
├─ realm/
│ ├─ Note.ts
│ ├─ NoteService.ts
│ ├─ RealmStore.ts
├─ App.tsx

To follow along locally, initialize a new React native app and install Realm JS.

Note.ts

This class defines the schema of a Realm object and will ultimately map to a table in Realm.

import uuid from 'react-native-uuid';
import Realm from 'realm';

export interface NoteProps {
  id?: string;
  content: string;
  createdOn?: Date;
  modifiedOn?: Date;
}

export default class Note {
  public id: string;
  public content: string;
  public createdOn?: Date;
  public modifiedOn?: Date;

  constructor({
    id = uuid.v4().toString(),
    content,
    createdOn,
    modifiedOn,
  }: NoteProps) {
    const now = new Date();

    this.id = id;
    this.content = content;
    this.createdOn = createdOn ?? now;
    this.modifiedOn = modifiedOn ?? now;
  }

  static schema: Realm.ObjectSchema = {
    name: 'Note',
    properties: {
      id: 'string',
      content: 'string',
      createdOn: 'date',
      modifiedOn: 'date',
    },
    primaryKey: 'id',
  };
}

RealmStore.ts

This class creates a new instance of the Realm which we’ll use in NoteService.ts to interact with the datastore.

import Note from './Note';
import {Realm} from '@realm/react';

export default new Realm({
  path: 'default',
  schema: [Note.schema],
  deleteRealmIfMigrationNeeded: __DEV__,
});

NoteService.ts

This class is responsible for loading data from the datastore and returning a paged result based on the paging properties.

Line 20 obtains a reference to the Notes Realm object but doesn’t actually issue any queries yet thanks to lazy loading which defers queries to only when you need them (accessing an object). This is effectively saying “give me access to all Notes but don’t load them into memory yet until I figure out which ones I want”.

Line 25 calls getPagedCollection which uses the provided paging options (e.g. page size, current page) to access a subset of the Realm Notes. Calling slice on the Realm Notes array is a form of access as we’re now directly interacting with individual notes. This issues a query against the Realm store and loads the subset of notes being accessed. For example, if 100 notes existed in array then array.slice(0, 10) would cause the first 10 notes to be loaded.

import {RealmObject} from 'realm/dist/public-types/Object';
import Note from './Note';
import realm from './RealmStore';

export interface PagingOptions {
  page: number;
  pageSize: number;
  hasNext: boolean;
}

export interface PagedCollection {
  result: Array;
  pagingOptions: PagingOptions;
}

export class NoteService {
  getPagedNotes(pagingOptions: PagingOptions): PagedCollection {
    // Lazy load the notes. These aren't materialized yet so no paging needs to occur
    // at the "realm" level.
    let notes = realm.objects('Note');
    notes = notes.sorted([['createdOn', false]]);

    // Access a subset of the notes based on the paging options (e.g. page, page size). This will
    // cause actual loading/materialization of the matching object(s) from the datastore.
    const pagedResult = this.getPagedCollection(notes, pagingOptions);
    console.log(
      `Paged Notes Count: ${
        pagedResult.result.length
      }, Paging options: ${JSON.stringify(pagedResult.pagingOptions)}`,
    );

    return pagedResult;
  }

  getPagedCollection(
    array: Realm.Results<RealmObject<T, never> & T>,
    pagingOptions: PagingOptions,
  ): PagedCollection {
    const {pageSize} = pagingOptions;
    let currentPage = pagingOptions.page;
    const totalPages = Math.ceil(array.length / pageSize);

    if (currentPage < 1) {
      currentPage = 1;
    }

    if (currentPage > totalPages) {
      currentPage = totalPages;
    }

    const start = (currentPage - 1) * pageSize;
    let end = start + pageSize;
    if (end > array.length) {
      end = array.length;
    }

    return {
      result: array.slice(start, end),
      pagingOptions: {
        ...pagingOptions,
        hasNext: end !== array.length,
      },
    };
  }
}

// singleton instance for convenience
export const noteService = new NoteService();

App.tsx

This component is responsible for maintaining paging state as the user interacts with the list. As the user scrolls and approaches the end of the list the next page is loaded.

Line 51 leverages the FlatList onEndReached callback which fires as the list breaches the threshold set by onEndReachedThreshold. The handler for this callback increments the current page state by one.

Line 35 of the useEffect hook declares pagingOptions.page as a dependency which means the function will be invoked any time the “page” value is modified.

Line 27 passes the current paging options state to the noteService.getPagedNotes function which returns a paged collection of notes from Realm. The loaded notes are then merged with any existing notes state which causes the component to rerender and the latest set of notes to be shown.

import React, {useState} from 'react';
import {FlatList, SafeAreaView, StatusBar, Text} from 'react-native';
import Note from './realm/Note';
import {noteService} from './realm/NoteService';

const itemStyle = {
  padding: 20,
  margin: 5,
  borderWidth: 1,
  borderColor: 'red',
};

function App(): React.JSX.Element {
  const [pagingOptions, setPagingOptions] = useState({
    page: 1,
    pageSize: 10,
    hasNext: true,
  });
  const [notes, setNotes] = useState<Note[]>([]);

  React.useEffect(() => {
    if (!pagingOptions.hasNext) {
      // no more pages remain so don't attempt to load anything.
      return;
    }

    const pagedResult = noteService.getPagedNotes(pagingOptions);
    // merge the new notes with the existing note state.
    const newNotes = [...notes, ...pagedResult.result];
    console.log(`Total notes loaded: ${newNotes.length}`);
    setPagingOptions(pagedResult.pagingOptions);
    setNotes(newNotes);

    return () => {};
  }, [pagingOptions.page]);

  return (
    <SafeAreaView>
      <StatusBar />
      <FlatList
        contentInsetAdjustmentBehavior="automatic"
        data={notes}
        extraData={notes.length}
        renderItem={item => {
          return (
            <Text key={item.item.id} style={itemStyle}>
              {item.item.content}
            </Text>
          );
        }}
        onEndReached={() => {
          if (pagingOptions.hasNext) {
            // breached the "end reached" threshold in the list and there's more notes to load,
            // increment the current page by one.
            setPagingOptions({
              ...pagingOptions,
              page: pagingOptions.page + 1,
            });
          }
        }}
        onEndReachedThreshold={0.5}
      />
    </SafeAreaView>
  );
}

export default App;

Additional Content

For convenience sake I used the below createNotes helper function to generate some notes for testing purposes in the Realm database. You can add a log statement to see the absolute path where your Realm database lives:

console.log(`Realm path: ${realm.path}`);
The following function was added to the NoteService.
createNotes() {
  for (let i = 0; i < 30; i++) {
    const createdOn = new Date();
    const note: Note = {
      id: `${i}`,
      content: `[${
        i + 1
      }] Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Habitant morbi tristique senectus et netus et malesuada fames. Etiam non quam lacus suspendisse faucibus interdum. Faucibus et molestie ac feugiat sed. Feugiat in ante metus dictum at. Morbi blandit cursus risus at ultrices mi tempus.`,
      createdOn,
      modifiedOn: createdOn,
    };
    realm.write(() => {
      realm.create<Note>('Note', note);
    });
  }
}

I added a button above the FlatList to invoke the helper function and generate the notes:

<Button
  title="Create sample notes"
  onPress={() => noteService.createNotes()}
/>

Xamarin iOS Detect if Ringer Is On Silent or Muted

Xamarin iOS Detect if Ringer Is On Silent or Muted

There’s currently no native support for detecting whether or not the device ringer is set to silent. This poses an issue when you want to leverage the state of the ringer to trigger some action within the app, such as notifying the user.

Fortunately there’s a fairly straightforward way to detect this on your own using a system sound.

Detecting Ringer State by Playing a System Sound

When the ringer is on silent it prevents any system sounds you attempt to play from actually playing. Conversely when the ringer is not on silent the sound will play as expected. We can leverage this behavior to confidently determine whether or not the device is on silent based on how quickly our system sound finishes playing.

Add Muted Sound File to Resources

The first thing we need to do is obtain a copy of a sound file that doesn’t actually make any noise. Here’s one for convenience. After downloading the file add it to the Resources folder in your iOS project.

I added mine under Resources > Audio:

Audio Resources Folder

Write Code to Determine Playback Time of System Sound

Now that we have the file in place we need to create a System Sound and determine how fast the sound played.

The SystemSound object has an observer method called AddSystemSoundCompletion, which as the name suggests lets us know when the sound finishes playing. The idea here is simple: find the time delta between when the sound started playing and when it finished. If the difference in time is negligible than we can safely assume the ringer is on silent. However, if the time delta is closer to how long the sound file would typically take to play, it’s likely the ringer is not on silent.

The following method can be added to your view controller or other class that needs to detect the state of the ringer and take action:

public void IsMuted(Action mutedCheckComplete) {
    // create an instance of the SystemSound object, pointing to your "mute" sound resource
    var soundFilePath = NSBundle.MainBundle.PathForResource("Audio/mute", "caf");
    var mutedSound = new SystemSound(new NSUrl(soundFilePath, false));

    // capture the start time of the sound
    DateTime startTime = DateTime.Now;

    mutedSound.AddSystemSoundCompletion(() => {
        // find the delta between start and end times to determine if the sound played or was cut short.
        var endTime = DateTime.Now;
        var timeDelta = (endTime - startTime).Milliseconds;
        var muted = timeDelta < 100;

        // perform the callback to the invoker of this method, letting them know we have an answer.
        mutedCheckComplete(muted);
    });

    mutedSound.PlaySystemSound();
}

In my tests the time delta was very close to zero when the ringer was on silent, and closer to ~300ms when not on silent. In the above snippet I consider anything less than 100ms to be considered muted.

Now that the method is created we can invoke it whenever we need to check the status of the ringer. In my case, I use this in the ViewWillAppear method of my view controller. To avoid any unexpected lag between loading the UI and performing this check, I added the method call to the dispatch queue as follows:

DispatchQueue.MainQueue.DispatchAfter(new DispatchTime(DispatchTime.Now, TimeSpan.FromMilliseconds(100)), () => {
    IsMuted((muted) => {
        Debug.WriteLine($"Is Muted: {muted}");
    });
});

There we have it, a fairly trivial approach at determining the state of the ringer.

Xamarin iOS UITableView GetCell Method Called for Invisible Cells

Xamarin iOS UITableView GetCell Method Called for Invisible Cells

In my Xamarin iOS application I’m leveraging the UITableView control to page through a collection of items in a performant manner. The UITableView uses the GetCell method of the UITableViewDataSource delegate to create or reuse instances of cells as they become visible on screen.

Great, that sounds efficient, and it is! However, in my application the GetCell method was being called once for every cell when the UITableView was initialized, including the invisible ones.

What gives?

This post spawned from a stackoverflow question I posted, then immediately found the answer to.

Replicating the Behavior By Example

The UITableView in question was added to a ViewController in the StoryBoard. Within the ViewController’s ViewDidLoad method, I have the following setup:

public override void ViewDidLoad() {
    base.ViewDidLoad();

    var model = new UIColor[] {
        UIColor.Green,
        UIColor.Red,
        UIColor.Magenta,
        UIColor.Cyan,
        UIColor.Blue,
        UIColor.Purple
    };

    SampleTableView.RowHeight = SampleTableView.Frame.Height;
    SampleTableView.Setup(model);
}

In short, a model consisting of a collection of colors is created and passed through to a Setup method on my custom UITableView, SampleTableView.
In addition to the setup, I already know the height of each row ahead of time, so the RowHeight property of the UITableView is set. As you can see, each row will take the full height of the UITableView. Swiping up or down will then reveal the next page.

Here’s what the SampleTableView and related dependencies look like:

public class SampleCell : UITableViewCell {
    public void Setup(UIColor color) {
        BackgroundColor = color;
    }
}

public class SampleTableViewDataSourceDelegate : UITableViewDataSource {
    public SampleTableViewDataSourceDelegate(UIColor[] model) {
        this.model = model;
    }

    private readonly UIColor[] model;

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) {
        Debug.WriteLine($"GetCell called. Row {indexPath.Row}");
        var reuseIdentifier = "SampleCell";

        var cell = tableView.DequeueReusableCell(reuseIdentifier) as SampleCell;

        cell = (cell ?? (cell = new SampleCell()));

        cell.Setup(model[indexPath.Row]);

        return cell;
    }

    public override nint NumberOfSections(UITableView tableView) {
        return 1;
    }

    public override nint RowsInSection(UITableView tableView, nint section) {
        return model.Length;
    }
}

public partial class SampleTableView : UITableView {
    public SampleTableView(IntPtr handle) : base(handle) {
        PagingEnabled = true;
    }

    private UIColor[] model;

    public void Setup(UIColor[] model) {
        this.model = model;

        DataSource = new SampleTableViewDataSourceDelegate(model);
    }
}

SampleCell
A custom cell that simply sets the background color to the one provided by the model.

SampleTableViewDataSourceDelegate
A derived class of UITableViewDataSource, which handles implementing the GetCell method. This class is responsible creating and reusing cells as they become visible.

SampleTableView
A derived class of UITableView, which handles initial setup of the UITableView via the Setup method, invoked by the containing ViewController.

We now have a fairly slimmed down example of a UITableView implementation. In the GetCell delegate method there’s a line of code that outputs a message to the log when it’s called. After running the application with Visual Studio in a simulator, the Visual Studio Output console shows the following:

[0:] GetCell called. Row 0
[0:] GetCell called. Row 1
[0:] GetCell called. Row 2
[0:] GetCell called. Row 3
[0:] GetCell called. Row 4
[0:] GetCell called. Row 5

Therein lies the issue; the GetCell method is called once for each cell in our model. Why? Didn’t I specify the RowHeight to be the height of the UITableView? If that’s true, and we know that GetCell should only be called when cells become visible, then why is it being called Model.Length number of times?

UITableView EstimatedRowHeight

Our RowHeight property is set to take up the entire UITableView. When the UITableView data source is initialized, however, the UITableView attempts to estimate the required row height for us on-the-fly via the EstimatedRowHeight property. The EstimatedRowHeight property was not set, effectively relying on the table view to calculate it for us. The solution to this particular problem then is to set the EstimateRowHeight property in addition to the RowHeight property.

Back in the ViewDidLoad method of the ViewController, adding the following line of code above the RowHeight setter did the trick:

 SampleTableView.EstimatedRowHeight = SampleTableView.Frame.Height; 

The Output log now shows what we’d expect, a single call to GetCell on initialize:

[0:] GetCell called. Row 0

jQuery Validation Rules for Dynamically Generated Content

jQuery Validation Rules for Dynamically Generated Content

jQuery Validation is a very convenient client-side validation framework that has made the implementation of client-side validation much more streamlined. For many web applications, introducing validation for a static form is as simple as defining the rules, messages and a handful of other (optional) settings. What about when we have dynamic content on our form? How can we define these rules for content we generate dynamically?

Follow along with this JSFiddle, which outlines the scenario described below.

Dynamically Set jQuery Validation Rules

We’ll start with a simple use case. Pretend for a moment you have a form with a few inputs: First Name, Last Name and Age. The jQuery Validation setup might look something like this:

var formValidationSettings = {
  ignore: '[readonly], :hidden',
  highlight: function(element) {
    $(element).addClass('has-error');
  },
  unhighlight: function(element) {
    $(element).removeClass('has-error');
  },
  errorElement: 'span',
  errorClass: 'help-block error',
  errorPlacement: function(error, element) {
    // do nothing, which suppresses the validation message
  },
  rules: {
    FirstName: {
      required: true
    },
    LastName: {
      required: true
    },
    Age: {
      required: true
    }
  }
};

// initialize the form's validator, applying the static form rules
$('form').validate(formValidationSettings);

We defined a few rules stating that each of the three inputs are required, as well as specified how and where our errors should be placed. This is fairly static content, allowing us to setup the jQuery Validation once and forget it. Not bad.

Now let’s bake in the ability for the user filling out the form to define a list of dependents. This will be done by introducing a grid where the user can hit “Add”, be presented a set of additional inputs to fill out, save the record and repeat. When the save button is clicked we want to trigger validation of this dynamic content.

Let’s say the dynamic inputs we present are Dependent Name and Relationship. We could define the rules for these inputs in the original form validation setup. However, that would trigger validation of all the other inputs on the form any time we attempt to save a dependent record. In other words, before we can successfully add a dependent record, all other inputs on the form must also be valid. That isn’t ideal. Instead, let’s define the dynamic input validation rules on the fly.

Fast forward a bit: the user clicked the “Add” button to enter a new dependent. They filled in the Dependent Name but neglected to enter the Relationship. They now attempt to save. Prior to triggering the jQuery Validation (e.g. $form.valid();), we must define our contextual dependent rules:

var dependentValidationSettings = {
  rules: {
    DependentName: {
      required: true
    },
    Relationship: {
      required: true
    }
  }
};

var saveDependent = function() {
  // create a deep copy (not reference) of the original form jQuery Validator settings
  var originalSettings = $.extend(true, {}, $form.validate().settings);

  // overwrite the original form settings with those for the dependent record
  var settings = $form.validate().settings;
  $.extend(settings, dependentValidationSettings);

  if ($form.valid()) {
    // save record
  }

  // reset the original settings after validating the dependent record
  $.extend(settings, originalSettings);
};

Let’s go over what’s happening here: when the “Save” button is clicked and our Save function triggered, we first create a deep copy of the original “form-wide” validation rules and set that aside. We’ll be using this later to revert our changes. Prior to asking jQuery to validate the form we alter the validation settings by overwriting the “rules” property with our dynamic “dependent-only” validation settings. jQuery Validation is now tuned in on the dependent inputs, leaving the rest of the form alone. At the very end of all this we unwind our rule changes and put jQuery Validation back to its original form-wide state.

There we have it, a way to focus the validation rules that jQuery Validation cares about on-the-fly.

K2 Blackpearl Re-Resolve Group to Users

K2 Blackpearl Re-Resolve Group to Users

We have a system built around the K2 Blackpearl workflow engine that routes requests to the appropriate destinations. We switched a number of users from one active directory domain to an entirely different one, which K2’s cache wasn’t aware of. This caused some users to be missed when resolving the workflow destination active directory group to its members.

Force K2 Workflow Activity to Re-Resolve AD Group Destination to Members

The first thing we need to do is force K2 to refresh its cache for the problematic active directory group.

  1. Navigate to the server where K2 is hosted.
  2. Find the ForceIdentityServiceRefresh application shipped with K2. For us, that’s in the C:\K2 folder.
  3. Enter the Group name, select the “Group” object type and check each checkbox to force a full cache refresh for the given group.K2 Cache Force Identity Refresh
  4. Click the Clear Identity Cache button.

Now that the cache is cleared K2 will have a reference to the latest members associated with the group in question. It’s time to make the K2 workflow re-resolve its destination:

  1. Open the K2 Workspace.
  2. Navigate to the Management Console.
  3. Within the Management Console menu tree, navigate to the Instances node of the workflow process that has a problematic instance, which is typically under the following path:

    K2ServerName -> Workflow Server -> Processes -> Your.Process.Name -> Your.Workflow.Name -> Instances

  4. Search for the workflow instance you want to re-resolve destinations for, select it, then click Goto Activity.K2 Workflow Instance
  5. Within the Goto Activity screen you’ll see a list of all available activities associated with the workflow. Select the same activity the workflow is currently at, then press OK.K2 Workflow GoTo Activity

The result of following the above steps will force the given instance of your K2 workflow process to re-evaluate the selected activity, effectively causing a re-resolution of the destination group to its members from K2’s refreshed cache. 

Download File with jQuery and Web API 2.0 IHttpActionResult

Download File with jQuery and Web API 2.0 IHttpActionResult

I came across a need to download a file through an AJAX request to a Web API 2.0 endpoint. A quick search revealed a fairly straightforward way to tackle this problem, which is to implement a custom IHttpActionResult (available in Web API 2.0) that sets up the HttpResponse in a way that can be digested by the client.

Create a Custom Web API 2.0 IHttpActionResult

The first step was to implement the IHttpActionResult as outlined below.

    public class ApiFileResult : IHttpActionResult {
        public ApiFileResult(string filePath, string contentType, string fileName = null) {
            if (string.IsNullOrWhiteSpace(filePath)) {
                throw new ArgumentNullException(nameof(filePath));
            }

            this.contentType = contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(filePath));
            var fileStream = File.OpenRead(filePath);
            var fileBytes = new byte[fileStream.Length];
            fileStream.Read(fileBytes, 0, fileBytes.Length);
            stream = new MemoryStream(fileBytes);

            this.fileName = fileName ?? Path.GetFileName(filePath);
        }

        public ApiFileResult(MemoryStream stream, string contentType, string fileName) {
            if (stream == null) {
                throw new ArgumentNullException(nameof(stream));
            }
            if (contentType == null) {
                throw new ArgumentNullException(nameof(contentType));
            }
            
            this.stream = stream;
            this.contentType = contentType;
            this.fileName = fileName;
        }

        private readonly string contentType;
        private readonly string fileName;
        private readonly MemoryStream stream;

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) {
            var bytes = stream.ToArray();
            var memoryStream = new MemoryStream(bytes);

            var response = new HttpResponseMessage(HttpStatusCode.OK) {
                Content = new StreamContent(memoryStream)
            };

            response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
            response.Content.Headers.ContentLength = memoryStream.Length;
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
                FileName = fileName
            };

            return Task.FromResult(response);
        }
    }

Once that’s in place we can use the new IHttpActionResult as our API’s return.

Create an ApiController Action That Returns Custom IHttpActionResult

Next up is creating an instance of this new custom Web API 2.0 IHttpActionResult class and using it as our API’s return type. Below is a fairly lightweight ApiController to demonstrate just that. The injected IBillingExportService class is used to generate a memory stream containing the contents of the file. We then new-up an instance of our custom ApiFileResult object, passing the file stream, file type and file name through.

    [RoutePrefix("api/v1/Billing")]
    public class BillingApiController : ApiController {
        public BillingApiController(IBillingExportService service) {
            this.service = service;
        }

        private readonly IBillingExportService service;

        [HttpPost, Route("Export", Name = "BillingExport")]
        public async Task<IHttpActionResult> GetBillingExport(int id) {
            var exportStream = await service.GetExportFile(id);
            return new ApiFileResult(exportStream, 
                                     "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 
                                     $"Billing Export {DateTime.Today:yyyy-MM-dd}{ExcelExport.WorkbookBuilder.ExcelFileExtension}");
        }
    }

Now that we have the API endpoint in place we can make a jQuery AJAX request to it, as follows:

    $.ajax({
            type: 'POST',
            cache: false,
            url: exportScheduledBillingUrl,
            data: serializeScheduledBillingGrid(),
            xhrFields: {
                    // make sure the response knows we're expecting a binary type in return.
                    // this is important, without it the excel file is marked corrupted.
                    responseType: 'arraybuffer'
                }
        })
    .done(function (data, status, xmlHeaderRequest) {
        var downloadLink = document.createElement('a');
        var blob = new Blob([data],
            {
                type: xmlHeaderRequest.getResponseHeader('Content-Type')
            });
        var url = window.URL || window.webkitURL;
        var downloadUrl = url.createObjectURL(blob);
        var fileName = '';

        // get the file name from the content disposition
        var disposition = xmlHttpRequest.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1) {
            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            var matches = filenameRegex.exec(disposition);
            if (matches != null && matches[1]) {
                fileName = matches[1].replace(/['"]/g, '');
            }
        }

        // Blob download logic taken from: https://stackoverflow.com/questions/16086162/handle-file-download-from-ajax-post
        if (typeof window.navigator.msSaveBlob !== 'undefined') {
            // IE workaround for "HTML7007" and "Access Denied" error.
            window.navigator.msSaveBlob(blob, fileName);
        } else {
            if (fileName) {
                if (typeof downloadLink.download === 'undefined') {
                    window.location = downloadUrl;
                } else {
                    downloadLink.href = downloadUrl;
                    downloadLink.download = fileName;
                    document.body.appendChild(downloadLink);
                    downloadLink.click();
                }
            } else {
                window.location = downloadUrl;
            }

            setTimeout(function () {
                    url.revokeObjectURL(downloadUrl);
                },
                100);
        }
    });

When the above Ajax call is triggered (i.e. a user clicks a button on your page) it’ll return the new custom IHttpActionResult you created. We then use the information provided by that result to build a Blob object. This Blob object enables us to generate an object URL which can be used to download the contents of our file.

Xamarin iOS MT1007 Failed to Launch the Application

Xamarin iOS MT1007 Failed to Launch the Application

After going through the free provisioning profile article I’ve been able to debug my Xamarin iOS app on a physical device. I wanted to verify what happens when the application gets installed for the first time, so I deleted the app from my phone. After running the Visual Studio debugger, the application was reinstalled successfully on my device, but failed to launch the debugger with the following message in the output log:

The app could not be launched on ‘iPhone’. Error: error MT1007: Failed to launch the application ‘/path/to/my/iOS.app’ on the device ‘iPhone’: Failed to launch the application ‘My.App.Namespace’ on the device ‘iPhone’: ESecurity. You can still launch the application manually by tapping on it.

Resolve the Xamarin iOS MT1007 Failed to Launch Error

The message sent to the Visual Studio output log was fairly vague. A quick Google search brought me to several different posts suggesting things like restarting my phone, updating Xcode and so on. Restarting wasn’t the solution and Xcode was already up-to-date. 

Enabling the Device Log prior to debugging gave me a bit more insight: after the error was raised, the following was output to the device log:

The request was denied by service delegate (SBMainWorkspace) for reason: Security (“Unable to launch my.application.namespace because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user”).

The line “its profile has not been explicitly trusted by the user” caught my interest, and made me believe something relate to my provisioning profile was undone. I plugged my phone into the Mac and opened my provisioning profile Xcode project. I then selected my device as the target and ran the application, which greeted me with an error message stating that my device does not trust the developer profile associated with the app.

You Just Need a Little Trust

While the Xamarin iOS MT1007 error can mean many things, in this case it boils down to trust. The solution to this trust issue is the following:

  1. On your iPhone, navigate to Settings -> General -> Device Management.
  2. Within Device Management, you should see your developer provisioning profile, click it.
  3. Trust the developer profile.

After trusting the profile you’ll see a callout stating:

Apps from developer “Your Profile” are trusted on this iPhone and will be trusted until all apps from the developer are deleted.”

Those last few words sum it all up. The problem was introduced the moment I uninstalled the app from my device, and rightfully so according to the relationship my device has with the developer profile.

Polaroid TV Turns On by Itself

Polaroid TV Turns On by Itself

We went out on a limb and purchased the Polaroid 4K Ultra HD TV. For the most part this TV was a good buy: great picture, sound and built-in functionality. One feature, however, made the TV appear to have a mind of its own. Periodically throughout the day we found that the TV turns on by itself as if there was a ghost inside the machine.

After doing some research I discovered the Consumer Electronics Control (CEC), which is a feature of HDMI ports. If you’ve ever turned your TV on by pressing the remote of an Apple TV or Amazon Fire Stick, you’ve made use of this handy feature. In short, it enables third-party systems like an Amazon Fire Stick to control the power of the TV itself, effectively avoiding the need for multiple remotes.

I never realized how much I enjoyed this feature until it was gone. That’s right, sadly the solution to our ghost problem was to disable CEC support. This feature is built-in to many different TV models, so this same fix may be relevant elsewhere. Sadly, not all manufacturers label CEC as obviously in the settings, so you may need to search for it. Fortunately, Polaroid stuck to the classic (and correct) CEC nomenclature. 

Disabling Polaroid TV Consumer Electronics Control CEC

Our Polaroid TV has a malfunction in the Consumer Electronics Control which caused the power to randomly cycle on when anything was plugged into the HDMI ports. While disabling this feature is a bummer, it did permanently resolve the issue (and beats unplugging the HDMI cord every night!). Here’s how you can test whether this solution works for you:

Press the Menu button on your remote, then choose Settings:

Polaroid TV Menu

In the Settings menu, select CEC:

Polaroid TV Settings Menu

Within the CEC Settings view, turn CEC Control: Off

Polaroid TV Settings CEC Off

Automatic Cat Laser Pointer Toy Using the Raspberry Pi

Automatic Cat Laser Pointer Toy Using the Raspberry Pi

Living in the city has shown me just how hard it can be to find an affordable apartment with a reasonable amount of space. Having two cats in such a small place doesn’t really give them much room to roam or pseudo hunt. Inspired by this cat tower, I decided to build an automatic cat laser pointer toy using my Raspberry Pi. The cats had one condition though, that it be a shark with a frikin’ laser beam attached to its heads (sound warning!).

If you’ve come across my automatic cat feeder post you might be thinking I’m automating myself out of the equation. Fear not, for we are still their primary source of entertainment, as they are ours.

Goal

The goal may be obvious at this point, but I like being explicit: to build an automatic cat laser pointer toy that is configurable, and can be triggered by a button.

Bonus Goal: configure and trigger this remotely. We’ll focus on the simpler solution first, and optionally over-engineer the project later on.

Prerequisites

You should have a configured Raspberry Pi ready to go. I used my Raspberry Pi 3B (40 GPIO pins), a 32gb MicroSD card (you could certainly go smaller) and the Raspbian distro (highly recommended). This guide was pretty straightforward and got me up and running in no time. 

The Parts

As with my automatic cat feeder post, I decided to break this down into four distinct parts:

  • Here in part one we’re introducing the project and what you’ll need to get it done.
  • In part two we’ll assemble all the pieces of the cat laser pointer toy.
  • Part three will focus on writing the python code, which will be responsible for moving the servo motors and turning on the laser beam at the push of a button.
  • Part four will cover the bonus goal of configuring and triggering remotely [optional].

Things You’ll Need for the Automatic Cat Laser Pointer Toy

  • Pan/tilt camera mount with 2x servos for controlling the movement of the laser.
  • 1x Laser diode to take over the world with.
  • 6x male-to-female, 6x any-to-female jumper wires to connect everything to the GPIO pins. What I mean by “any” here is that “it doesn’t matter“, because we’ll be cutting off that end of the wire and soldering it anyway.
  • 1x NPN Transistor to logically control the Pi’s 3v3 power rail through a GPIO pin, and toggle the laser on/ off. You only need one of these. eBay may have better options in terms of quantity, or hey, even stop at a physical store like Radioshack!
  • SHARKS! because it really is hilarious.
  • 5v 2.5A power supply to power the Pi, servos and lasers. The servos and laser draw a good amount of current, so we need to make sure the power supply is capable of supporting it.
  • Raspberry Pi Case to house the Pi and wiring. This isn’t strictly necessary, but it made for a convenient way to mount the laser and control the wiring.
  • 1x Push Button to manually engage the laser. I got mine in a starter kit, but you can buy them separately if you’d like.
  • Velcro to mount the shark (or laser if you opted out of adding a shark, which saddens me) to the pan/tilt mount. I used velcro here so I can conveniently point the laser in the opposite direction, which provides an entirely different available range for the pan/tilt mount.
  • Electrical tape to wrap the soldered wires.

The Tools

  • [Optional] Power drill to make holes in the Raspberry Pi case to fasten the pan/tilt mount to it. If I did this project over, I would have used velcro as my fastener as it’s much simpler and less intrusive. Your call.
  • Hot glue gun to glue the laser to the shark. Again, any other adhesive would suffice if you don’t already have a hot glue gun.
  • Soldering iron to solder some of the wiring together.
  • Wire stripper for when we get to stripping and soldering a few of the wires.
  • Tiny philips screwdriver to assemble the pan/tilt mount.

Conclusion and Next Steps

At this point we covered the basics of what it is we’re trying to build here in part one, and what you’ll need to accomplish it. Head over to part two where we’ll be focusing on assembling all the pieces.

Ahead of the game? Nice! Part three has the Python code, and part four sets up a way to remotely control the whole thing.