Help us understand the problem. What is going on with this article?

Xamarin.Authからの移行

More than 1 year has passed since last update.

背景

Visual Studio for Mac を 2019 にアップデートしたら Xamarin.iOS のアプリが動かなくなった。

Xamarin.Auth の AccountStore.FindAccountsForServiceAsync を呼ぶだけでエラーが起きるようになっている。

https://github.com/xamarin/Xamarin.Auth/issues/370 にissueが上がっており、対策は

  1. Xamarin.iOSのダウングレード(12.2)
  2. Xamarin.Essentials の SecureStorage への移行。

のいずれか。

前者は影響範囲が全アプリに及ぶうえに、Xamarin.Auth のこのクラスは非推奨のため、後者を選択。

やり方

Migration Guide にあるように、次のようなヘルパークラスをつくって移行すればよい。

using Newtonsoft.Json;
using Xamarin.Auth;
using Xamarin.Essentials;

public class SecureStorageAccountStore
{
    public static async Task SaveAsync(Account account, string serviceId)
    {
        // Find existing accounts for the service
        var accounts = await FindAccountsForServiceAsync(serviceId);

        // Remove existing account with Id if exists
        accounts.RemoveAny(a => a.Username == account.Username);

        // Add account we are saving
        accounts.Add(account);

        // Serialize all the accounts to javascript
        var json = JsonConvert.SerializeObject(accounts);

        // Securely save the accounts for the given service
        await SecureStorage.SetAsync(serviceId, json);
    }

    public static async Task<List<Account>> FindAccountsForServiceAsync(string serviceId)
    {
        // Get the json for accounts for the service
        var json = await SecureStorage.GetAsync(serviceId);

        try {
            // Try to return deserialized list of accounts
            return JsonConvert.DeserializeObject<List<Account>>(json);
        } catch { }

        // If this fails, return an empty list
        return new List<Account>();
    }

    public static async Task MigrateAllAccountsAsync(string serviceId, IEnumerable<Account> accountStoreAccounts)
    {
        var wasMigrated = await SecureStorage.GetAsync("XamarinAuthAccountStoreMigrated", "0");

        if (wasMigrated == "1")
            return;

        await SecureStorage.SetAsync("XamarinAuthAccountStoreMigrated", "1");

        // Just in case, look at existing 'new' accounts
        var accounts = await FindAccountsForServiceAsync(serviceId);

        foreach (var account in accountStoreAccounts) {

            // Check if the new storage already has this account
            // We don't want to overwrite it if it does
            if (accounts.Any(a => a.Username == account.Username))
                continue;   

            // Add the account we are migrating
            accounts.Add(account);
        }

        // Serialize all the accounts to javascript
        var json = JsonConvert.SerializeObject(accounts);

        // Securely save the accounts for the given service
        await SecureStorage.SetAsync(serviceId, json);
    }
}

※ 上は挙げられているコードそのままだが、実際には System.Linq などの import をたす必要あり。

問題

が、結局この前後のデータのマイグレーションにも Find... が必要なため、この事態が起きてしまうということ。許容できない場合は Xamarin.Native でキーチェーンにアクセスして取り出す処理を書く必要がある。

もう一点、iOS SDK の問題だが、シミュレータ上では Entitlements.plist の編集が必要になる。通常(実機で使う場合)は不要のため、地味にストレスになる。

https://docs.microsoft.com/ja-jp/xamarin/essentials/secure-storage?context=xamarin%2Fandroid&tabs=ios

karak
最近は C#, TypeScript, React, Xamarin.Forms と AWS Lambda 界隈にいます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした