Xamarin 与多个 Android 和 iOS 应用共享基础 Android 和 iOS 项目
Xamarin Sharing A Base Android and iOS Project with multiple Android and iOS apps
我设置了一个项目,以便我可以为我们的每个客户提供不同风格的应用程序,并且我正在尝试简化我们的设计。
目前它已经设置好,所以我们有我们的 PCL,然后是每个客户的 Android 和 iOS 项目。这意味着如果我们更改应用程序端代码的任何内容,我们必须在每个项目中手动更改它。
我一直在尝试改变它,所以我们有我们的 PCL 和一个基础 Android 和 iOS 项目,它有平台特定的接口代码,其他每个项目都有然后可以继承它们各自的颜色样式、图像和包标识符。
例如
- PCL 项目(共享代码、表格等)
- Android.Shared(共享 resources/localisations 为 android apps/platform 特定代码)
- Android.Client1Theme(Client1 的自定义资源(徽标、颜色等))
Android.Client2Theme(Client2 的自定义资源(徽标、颜色等))
iOS.Shared(共享resources/localisations为androidapps/platform具体代码)
- iOS.Client1Theme(Client1 的自定义资源(徽标、颜色等))
- iOS.Client2Theme(Client2 的自定义资源(徽标、颜色等))
通过创建一个新的 android 项目并添加对共享 android 项目和 PCL 的引用,我已经使它适用于 Android。
我无法以同样的方式为 iOS 工作。很接近了,iOS 应用程序编译为具有正确样式的新应用程序,但是 DependencyService 在尝试访问接口方法时崩溃。
DependencyService.Get<ISystemFunctions>().ToggleTorch();
exception thrown on iOS interface access
下面是我共享项目中的接口代码,但我不认为这是问题所在,而是 DependencyService 找不到它。
[assembly: Dependency(typeof(SystemFunctions_iOS))]
namespace SharedApp.iOS.iOS_Interfaces
{
public class SystemFunctions_iOS : ISystemFunctions
{
public SystemFunctions_iOS()
{ }
public void ToggleTorch()
{
var device = AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Video);
if (device == null)
return;
device.LockForConfiguration(out NSError error);
if (error != null)
{
device.UnlockForConfiguration();
return;
}
else
{
device.TorchMode = device.TorchMode == AVCaptureTorchMode.On ? AVCaptureTorchMode.Off : AVCaptureTorchMode.On;
device.UnlockForConfiguration();
}
}
}
}
让我知道是否还有其他我可以分享的内容来帮助解决这个问题。
找到了我的问题的解决方案
在 iOS.Shared 的 AppDelegate 中删除行
[Register("AppDelegate")]
//[Register("AppDelegate")] NEEDED TO REMOVE THIS
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
在 iOS.ClientThemeX 的 AppDelegate 中添加行
var systemFunctions_iOS = new iOS.Shared.iOS_Interfaces.SystemFunctions_iOS();
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
// DO NOT REMOVE THIS. It breaks without it. Don't know why
// but a similar row will need to be added for each interface added to the project
var systemFunctions_iOS = new SharedApp.iOS.iOS_Interfaces.SystemFunctions_iOS();
return base.FinishedLaunching(app, options);
}
}
从共享项目中删除 AppDelegate 寄存器是有道理的,但我不确定为什么我需要用我的接口声明一个新对象才能工作。
问题中的这个接口构造函数是空的。
如果有人能对此有所了解,我们将不胜感激,或者如果有任何关于更简单的方法的建议。
我设置了一个项目,以便我可以为我们的每个客户提供不同风格的应用程序,并且我正在尝试简化我们的设计。 目前它已经设置好,所以我们有我们的 PCL,然后是每个客户的 Android 和 iOS 项目。这意味着如果我们更改应用程序端代码的任何内容,我们必须在每个项目中手动更改它。
我一直在尝试改变它,所以我们有我们的 PCL 和一个基础 Android 和 iOS 项目,它有平台特定的接口代码,其他每个项目都有然后可以继承它们各自的颜色样式、图像和包标识符。
例如
- PCL 项目(共享代码、表格等)
- Android.Shared(共享 resources/localisations 为 android apps/platform 特定代码)
- Android.Client1Theme(Client1 的自定义资源(徽标、颜色等))
Android.Client2Theme(Client2 的自定义资源(徽标、颜色等))
iOS.Shared(共享resources/localisations为androidapps/platform具体代码)
- iOS.Client1Theme(Client1 的自定义资源(徽标、颜色等))
- iOS.Client2Theme(Client2 的自定义资源(徽标、颜色等))
通过创建一个新的 android 项目并添加对共享 android 项目和 PCL 的引用,我已经使它适用于 Android。
我无法以同样的方式为 iOS 工作。很接近了,iOS 应用程序编译为具有正确样式的新应用程序,但是 DependencyService 在尝试访问接口方法时崩溃。
DependencyService.Get<ISystemFunctions>().ToggleTorch();
exception thrown on iOS interface access
下面是我共享项目中的接口代码,但我不认为这是问题所在,而是 DependencyService 找不到它。
[assembly: Dependency(typeof(SystemFunctions_iOS))]
namespace SharedApp.iOS.iOS_Interfaces
{
public class SystemFunctions_iOS : ISystemFunctions
{
public SystemFunctions_iOS()
{ }
public void ToggleTorch()
{
var device = AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Video);
if (device == null)
return;
device.LockForConfiguration(out NSError error);
if (error != null)
{
device.UnlockForConfiguration();
return;
}
else
{
device.TorchMode = device.TorchMode == AVCaptureTorchMode.On ? AVCaptureTorchMode.Off : AVCaptureTorchMode.On;
device.UnlockForConfiguration();
}
}
}
}
让我知道是否还有其他我可以分享的内容来帮助解决这个问题。
找到了我的问题的解决方案
在 iOS.Shared 的 AppDelegate 中删除行
[Register("AppDelegate")]
//[Register("AppDelegate")] NEEDED TO REMOVE THIS
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
在 iOS.ClientThemeX 的 AppDelegate 中添加行
var systemFunctions_iOS = new iOS.Shared.iOS_Interfaces.SystemFunctions_iOS();
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
// DO NOT REMOVE THIS. It breaks without it. Don't know why
// but a similar row will need to be added for each interface added to the project
var systemFunctions_iOS = new SharedApp.iOS.iOS_Interfaces.SystemFunctions_iOS();
return base.FinishedLaunching(app, options);
}
}
从共享项目中删除 AppDelegate 寄存器是有道理的,但我不确定为什么我需要用我的接口声明一个新对象才能工作。 问题中的这个接口构造函数是空的。
如果有人能对此有所了解,我们将不胜感激,或者如果有任何关于更简单的方法的建议。