Scan ean code on iOS app

This commit is contained in:
Michał Zieliński
2025-07-17 19:17:27 +02:00
parent 2a42f16daf
commit b673fd2da3
8 changed files with 255 additions and 23 deletions

View File

@@ -2,6 +2,8 @@
<PropertyGroup>
<TargetFramework>net8.0-ios</TargetFramework>
<GenerateXcodeProject>true</GenerateXcodeProject>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
@@ -21,15 +23,15 @@
<Nullable>enable</Nullable>
<!-- Display name -->
<ApplicationTitle>Bimix.UI.Mobile</ApplicationTitle>
<ApplicationTitle>Bimix</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.bimix.ui.mobile</ApplicationId>
<ApplicationId>cloud.bimit.bimix</ApplicationId>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">24.0</SupportedOSPlatformVersion>
@@ -38,6 +40,14 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'iPhone'">
<ApplicationId>cloud.bimit.bimix</ApplicationId>
<CodesignKey>Apple Development: Michal Zielinski (2F35ZHMBTB)</CodesignKey>
<CodesignProvision>bimix-local</CodesignProvision>
<RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4"/>
@@ -66,11 +76,12 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="$(MauiVersion)"/>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.1"/>
<PackageReference Include="MudBlazor" Version="8.8.0"/>
<PackageReference Include="ZXing.Net.MAUI" Version="0.4.0" />
<PackageReference Include="ZXing.Net.MAUI.Controls" Version="0.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bimix.UI.Shared\Bimix.UI.Shared.csproj"/>
</ItemGroup>
</Project>
</Project>

View File

@@ -1,6 +1,9 @@
using Bimix.UI.Shared.Extensions;
using Bimix.UI.Mobile.Services;
using Bimix.UI.Shared.Extensions;
using Bimix.UI.Shared.Interfaces;
using Microsoft.Extensions.Logging;
using MudBlazor.Services;
using ZXing.Net.Maui.Controls;
namespace Bimix.UI.Mobile;
@@ -11,12 +14,21 @@ public static class MauiProgram
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseBarcodeReader()
.ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); });
builder.Services.AddMauiBlazorWebView();
builder.Services.AddMudServices();
if (DeviceInfo.Platform == DevicePlatform.iOS)
{
builder.Services.AddSingleton<IScannerService, ScannerService>();
}
else
{
builder.Services.AddSingleton<IScannerService, NoOpScannerService>();
}
var baseUrl = GetApiBaseUrl();
builder.Services.AddSharedServices(baseUrl);

View File

@@ -0,0 +1,140 @@
using Bimix.UI.Shared.Interfaces;
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;
namespace Bimix.UI.Mobile.Services;
public class ScannerService : IScannerService
{
public bool IsAvailable => true;
public async Task<string?> ScanBarcodeAsync()
{
try
{
if (!IsAvailable)
return null;
var hasPermission = await RequestCameraPermissionsAsync();
if (!hasPermission)
return null;
var tcs = new TaskCompletionSource<string?>();
await MainThread.InvokeOnMainThreadAsync(async () =>
{
var scanner = new CameraBarcodeReaderView
{
Options = new BarcodeReaderOptions
{
Formats = BarcodeFormats.OneDimensional | BarcodeFormats.TwoDimensional,
AutoRotate = true,
Multiple = false
},
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Colors.Black
};
scanner.BarcodesDetected += async (sender, e) =>
{
if (e.Results?.Any() == true)
{
var barcode = e.Results.First();
// Wykonaj operacje UI na głównym wątku
await MainThread.InvokeOnMainThreadAsync(async () =>
{
try
{
await Microsoft.Maui.Controls.Application.Current?.MainPage?.Navigation.PopModalAsync()!;
tcs.TrySetResult(barcode.Value);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error closing modal: {ex.Message}");
tcs.TrySetException(ex);
}
});
}
};
var cancelButton = new Button
{
Text = "Anuluj",
BackgroundColor = Colors.Red,
TextColor = Colors.White,
Margin = new Thickness(20),
HorizontalOptions = LayoutOptions.Center
};
cancelButton.Clicked += async (sender, e) =>
{
try
{
await Microsoft.Maui.Controls.Application.Current?.MainPage?.Navigation.PopModalAsync()!;
tcs.TrySetResult(null);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error closing modal: {ex.Message}");
tcs.TrySetException(ex);
}
};
var stackLayout = new StackLayout
{
Children =
{
new Label
{
Text = "Skieruj kamerę na kod kreskowy",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Start,
Margin = new Thickness(20),
FontSize = 18,
TextColor = Colors.White
},
scanner,
cancelButton
},
BackgroundColor = Colors.Black,
Spacing = 0
};
var scannerPage = new ContentPage
{
Title = "Skanuj kod",
Content = stackLayout,
BackgroundColor = Colors.Black
};
await Microsoft.Maui.Controls.Application.Current?.MainPage?.Navigation.PushModalAsync(scannerPage)!;
});
var result = await tcs.Task;
System.Diagnostics.Debug.WriteLine($"Scanner returned: {result}");
return result;
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine($"Scanner error: {e.Message}");
return null;
}
}
public async Task<bool> RequestCameraPermissionsAsync()
{
try
{
var status = await Permissions.RequestAsync<Permissions.Camera>();
return status == PermissionStatus.Granted;
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine($"Permission error: {e.Message}");
return false;
}
}
}