1Password Extension for Xamarin.iOS apps

1Password is one of my favorite application on Mac and iPhone. It’s 1Password Logoworking pretty well across devices, browsers (Chrome/Safari in my cases). With one unique master password, 1Password enables different strong, complex passwords to all online socials.

There is a bunch of iOS applications on Store that use 1Password login side already, see here: https://blog.agilebits.com/1password-apps . Most of the popular apps are named here. Below are how it looks on Dropbox and Pluralsight (notice the 1Password icon?)

1Password Extension for Xamarin.iOS apps - Demo Dropbox 1Password Extension for Xamarin.iOS apps - Demo Pluralsight

 

How do we add this extension to our iOS application? There is “1Password Extension for iOS Apps” that helps iOS developers support using 1Password login inside their applications, check out https://github.com/AgileBits/onepassword-app-extension, but only for Objective-C and Swift. Well, how about Xamarin?

Xamarin.iOS Binding for 1Password Extensions

Yes, I made the bindings library for it, check this Nuget package: 1PasswordExtension for Xamarin.iOS

The source code is hosted on Github: https://github.com/trinnguyen/onepassword-app-extension-xamarin

Anyone who is curious about how it is built can look at there and built their own DLL too, it fetches the latest Release of the original Objective-C library to build CocoaTouch framework.

The binding ApiDefinitions class is generated by using Objective Sharpie with CocoaPods components, I hope to have some time to write about it later.

Integrate to 1Password to your Xamarin.iOS app

1. Install Nuget package and add assets

Simply install the Nuget package (bindings of 1Password Extension) to Xamarin.iOS project

Install-Package Xamarin.1PasswordExtension

Add 1Password.xcassets catalog to the application bundle, these images are provided by 1Password Team to help user recognize the button. This resource can be found on my Github repo or the original library

2. Add LSApplicationQueriesSchemes in Info.plist

1Password extension uses UIApplication.CanOpenURL to check whether the app extension is available, with value “org-appextension-feature-password-management“, thus any application that supports password management actions can be visible.

One iOS 9+, application need to whitelist org-appextension-feature-password-management in LSApplicationQueriesSchemes

  • Open your Info.plist file, tab Source
  • Add new row: LSApplicationQueriesSchemes (array) with item: org-appextension-feature-password-management

Play with source code

There are 4 use cases that normally integration works, for details check out document of the original library. In this article, I will show how it works on Xamarin with C# code

A demo Xamarin.iOS application is provided on my Github repo, covers 3 use cases. For webView, check below sample code.

check app Extension is available

Hide 1Password button if the App Extension is not visible (1Password app is not installed on iOS device yet)

Use Case #1: Native App Login

Use Case #2: New User Registration

Use Case #3: Change Password

Use Case #4: Web View Filling

 

OpenCV for Xamarin.iOS

Updated: Last 3 years I’ve worked on a Xamarin cross-platforms applications via iOS, Android, Windows Phone 8 which required using OpenCV for face detector and recognition. Even OpenCV has official frameworks for both iOS (ObjC) but it is pretty hard to make fully binding on Xamarin.iOS because most parts of framework are written on C/C++.

Below tutorial is a workaround solution, but effectively, for getting native OpenCV for Xamarin.iOS.

Overview

The idea is creating iOS Static library (CocoaTouch library) as a wrapper for specific functions (by requirements).  This wrapper is written on Objective-C and implemented by communicating with OpenCV C++ classes.

Let’s go through a sample spec: detect faces from an image

iOS Static Library: Simple library with one function: Detect faces on an image with OpenCV, export .a file for using on Xamarin

Xamarin.iOS Binding project: Create a C# wrapper for static library, iOS Application: demo how binding and function of static library, detect faces on an image and draw them with red rectangle on image

Step by step: OpenCV on Xamarin.iOS

First, create iOS Static Library

Should have an Objective-C library for wrapping all features that will work with OpenCV:

  • Download opencv2.framework from OpenCV site (http://opencv.org/downloads.html)
  • XCode: Create iOS Static Library project with a Objective-C class that contains required functions (can be multiple classes for management), named FaceDetector
#import <Foundation/Foundation.h>

@interface OpenCVUtils : NSObject
+ (cv::Mat)cvMatFromUIImage:(UIImage *)image;
+ (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat;
+ (CGRect) cgRectFromCVRect:(cv::Rect) cvRect;
@end
@interface FaceDetector : NSObject
- (id) initWithFaceCascade:(NSString*) filePath;
- (NSArray*) detectFaces:(UIImage*) image;
@end
  • Build iOS Static Library and get libFaceDetector.a file

Second, Create Xamarin.iOS Binding

  • Xamarin Studio: New Solution -> iOS -> Unified API -> iOS Binding Project
  • Drag libFaceDetector.a to Binding project
  • Back to opencv2.framework file, open it, go to opencv2.framework -> Versions -> A -> opencv2. Rename this file to opencv2.a. Drag this to Binding project. (This binary file is required as reference from libFaceDetector.a)
  • Open opencv2.linkwith.cs, add LinkerFlags and Frameworks
[assembly: LinkWith ("opencv2.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator, ForceLoad = true, LinkerFlags="-lc++", Frameworks="Accelerate AssetsLibrary AVFoundation CoreGraphics CoreImage CoreMedia CoreVideo QuartzCore UIKit Foundation")]
  • ApiDefinition.cs : Define interfaces for working with libFaceDetector.a . Can create manually if experienced with Xamarin.iOS Binding Metadata or using Objective Sharpie (command line tool)
[BaseType (typeof (NSObject))]
interface FaceDetector {
 //- (id) initWithFaceCascade:(NSString*) filePath;
 [Export ("initWithFaceCascade:")]
 IntPtr Constructor (string filePath);

 //- (NSArray*) detectFaces:(UIImage*) image;
 [Export ("detectFaces:")]
 NSArray DetectFaces(UIImage image);
}
  • Create Xamarin.iOS project, add reference to above Xamarin.iOS Binding project, try use C# wrapper classes

UIImage srcImage = UIImage.FromBundle("lena1");
NSArray arrFaces = _faceDetector.DetectFaces(srcImage);

Source code

Get the full source code: https://github.com/trinnguyen/xamarin.ios-opencv