Xamarin.iOS controle en toegang camera

move-to-ios-icon

Wanneer je een app ontwikkeld en je wilt hierin bijvoorbeeld gebruik maken van een bepaalde privacy gevoelige data bronnen (camera, microfoon, gallery, contacts etc.) Dan moet je hier de gebruiker om toestemming voor vragen, in dit stukje laat ik zien hoe je de camera toegang kunt controleren van de app, en hoe je bij de eerste keer opstarten van de app de gebruiker om toestemming kunt vragen om de camera te gebruiken. Let op wanneer er gebruik wordt gemaakt van asynchrone code, dat je wel wacht op de gebruikers interactie op de vragen. Bijvoorbeeld: await cameraAccess();

        public async Task cameraAccess()
        {
            // Ophalen camera toegangs status
            AVAuthorizationStatus authStatus = AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video);

            if (authStatus == AVAuthorizationStatus.Authorized)
            {
                // Ja we hebben toegang tot de camera
                return true;
            }
            else if (authStatus == AVAuthorizationStatus.Denied)
            {
                // Nee camera toegang stat uit
                return false;
            }
            else if (authStatus == AVAuthorizationStatus.Restricted)
            {
                // restricted, gebeurt normaal gesproken niet
                return false;
            }
            else if (authStatus == AVAuthorizationStatus.NotDetermined)
            {
                // Niet bekend, waarschijnlijk eerste keer dat de app gestart wordt
                bool CamresultData = await AVCaptureDevice.RequestAccessForMediaTypeAsync(AVMediaType.Video);
                return CamresultData;
            }
            else
            {
                return false;
            }
        }

Xamarin cross platform forms, uitvoeren native code (iOs/Android) via interfaces

xamarin-logo

Xamarin Forms is een cross platform framework, met als targets: Android, iOS, UWP. Heel mooi maar soms is het noodzakelijk om bepaalde functionaliteit aan te roepen die alleen native op het doelplatform beschikbaar is. Denk hierbij bijvoorbeeld aan het uitlezen van het serienummer van het apparaat, hoe ga je deze informatie verwerken in je applicatie? Hier bestaat een hele mooie oplossing voor: interfaces

Een interface bestaat uit:

  • één klasse(class) die we gebruiken in deel van de gedeelde code;
  • en één klasse(class) voor elke native platform.

In de klasse(class) die we in de shared code definiëren maken we de interface klasse(class), deze klasse(class) bevat alle functies die we ook in de native code class moeten programmeren, zie code hieronder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExampleApp
{
    public interface getHWId
    {
        string DUID();
    }
}

Android native code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using System.Threading.Tasks;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Text;
using ExampleApp.Droid;
using Android.Graphics;
using Android.Content.PM;
using Android.Hardware;
[assembly: Xamarin.Forms.Dependency(typeof(IgetHWId))]

namespace ExampleApp.Droid
{
    class IgetHWId : getHWId
    {
        public string DUID()
        {
            string deviceId;
            deviceId = Android.OS.Build.Serial;
            return (deviceId);
        }
    }
}

iOs native code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using ExampleApp.iOS;
using UIKit;
using Xamarin.Forms.Platform.iOS;
using WebKit;
using CoreGraphics;
using AVKit;
using AVFoundation;

[assembly: Xamarin.Forms.Dependency(typeof(IgetHWId))]

namespace ExampleApp.iOS
{
    class IgetHWId : getHWId
    {
        public string DUID()
        {
            string deviceId;
            deviceId = UIKit.UIDevice.CurrentDevice.IdentifierForVendor.AsString();
            return (deviceId);
        }
    }
}

Nu nog het stukje code om de DUID() functie aan te roepen vanuit de platform shared code:

    private getHWId nativeInterface;
    nativeInterface = new DependencyService.Get();
    Debug.WriteLine("Uniek hardware id = " + nativeInterface->DUID());

Xamarin Forms / iOS / Appsize

xamarin-logo

Apple hanteert in de app store een limiet van 100 megabyte voor apps zodat ze downloadbaar blijven via lte/3g (mobiele netwerken) . Ook wordt de app size groter wanneer deze geüpload/ingediend wordt in de app store, bijvoorbeeld een app binary van 53 megabyte kan bijvoorbeeld 110 megabyte worden. Dit komt omdat de binary’s aangepast worden voor specifieke platformen. Maar door middel van wijzigingen in de linker en builder kun je de app size reduceren zodat hij na upload in de app store ook onder de 100 megabyte blijft. Mijn app ging van 53 megabyte naar 20 megabyte.

Aanpassingen die ik hiervoor gedaan heb zijn:

  • iOS build generally, General, linker behavior op: link SDK assemblies only
  • iOS build generally, Advanced, generic value type sharing: ja

Optioneel kun je nog builden voor een specifieke platform architectuur, dit raad echter af omdat dit app compatibiliteit niet ten goede komt.

postvak-in-debugachtergrondonderzoek-nl-outlook_2postvak-in-debugachtergrondonderzoek-nl-outlook