iOS 无法使用 Xamarin 和 MvvmCross 拍照
Unable to take picture with Xamarin and MvvmCross on iOS
我正在开发一个 iOS 应用程序,它需要能够拍照(用来做一些事情)。
我将 Xamarin 与 MvvmCross 6.2.0 一起使用,并导入了 MvxPictureChooser 插件。
我已将 NSPhotoLibraryAddUsageDescription 添加到我的 Info.plist
...
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs to be able to save your expense attachments as images.</string>
<key>UIRequiresFullScreen</key>
<true/>
...
现在,当我尝试使用 ChoosePictureFromLibrary 时,一切顺利。
另一方面,如果我尝试使用 TakePicture(int, int, Action, Action),我会得到一个包含错误的异常:NSInvalidArgumentException 原因:源类型 1 不可用
我的代码如下所示:
private void DoTakePictureCommand()
{
var picChooser = Mvx.IoCProvider.Resolve<IMvxPictureChooserTask>();
try
{
picChooser.TakePicture(_envProvider.Environment.JpegSize, _envProvider.Environment.JpegQuality, (stream) =>
{
using (var ms = new MemoryStream())
{
stream.CopyToAsync(ms);
ReceiptJpegData = ms.ToArray();
_log.Trace("Picture bytes: {0}", ReceiptJpegData.Length);
InvokeOnMainThread(ImageComplete);
}
}, () =>
{
});
}
catch (Exception e)
{
Debug.Write(e);
}
}
完整的错误在这里:
[0:] Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Source type 1 not available
Native stack trace:
0 CoreFoundation 0x000000011c41429b __exceptionPreprocess + 331
1 libobjc.A.dylib 0x000000011d2e8735 objc_exception_throw + 48
2 UIKitCore 0x0000000126d03553 -[UIImagePickerController sourceType] + 0
3 xxxiOS 0x000000010ed801b9 xamarin_dyn_objc_msgSend + 217
4 ??? 0x0000000141e58257 0x0 + 5400527447
at ObjCRuntime.Runtime.ThrowNSException (System.IntPtr ns_exception) [0x00000] in
/Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/ObjCRuntime/Runtime.cs:398
at ObjCRuntime.Runtime.throw_ns_exception (System.IntPtr exc) [0x00000] in
/Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/runtime/Delegates.generated.cs:126
at (wrapper native-to-managed) ObjCRuntime.Runtime.throw_ns_exception(intptr)
--- End of stack trace from previous location where exception was thrown --- at (wrapper managed-to-native)
ObjCRuntime.Messaging.void_objc_msgSend_Int64(intptr,intptr,long) at
UIKit.UIImagePickerController.set_SourceType
(UIKit.UIImagePickerControllerSourceType value) [0x00015] in
/Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/UIKit/UIImagePickerController.g.cs:587
at
MvvmCross.Plugin.PictureChooser.Platforms.Ios.MvxImagePickerTask.TakePicture
(System.Int32 maxPixelDimension, System.Int32 percentQuality,
System.Action`1[T] pictureAvailable, System.Action assumeCancelled)
[0x00014] in <8539a731432e4b45b49dd5ca22de5afd>:0 at
xxx.DoTakePictureCommand
() [0x0000d] in
C:\Users\xxxx\Documents\IdeaProjects\xxxx\xxxx\XXX.Core\ViewModels\AddExpenseViewModel.cs:447
0 CoreFoundation 0x000000011c41429b
__exceptionPreprocess + 331 1 libobjc.A.dylib 0x000000011d2e8735 objc_exception_throw + 48 2 UIKitCore
0x0000000126d03553 -[UIImagePickerController sourceType] + 0 3
xxxiOS 0x000000010ed801b9
xamarin_dyn_objc_msgSend + 217 4 ???
0x0000000141e58257 0x0 + 5400527447 2018-09-27 23:15:03.294036+0200
xxxiOS[46563:4418172] 2018-09-27 11:15:03 [TRACE]
(MvvmCross.Logging.MvxLog) iOSNavigation 2018-09-27
23:15:03.294886+0200 xxxiOS[46563:4418172] 2018-09-27
11:15:03 [TRACE] (MvvmCross.Logging.MvxLog) PresentationAttribute not
found for AddExpenseView. Assuming animated Child presentation
CalabashServer | XTC_SKIP_LPSERVER_TOKEN is not in the app environment
CalabashServer | Will start LPServer with identifier:
c36c12ce937d044d55d0c208f9d4502868233513
更新
我现在已经尝试将代码部署到我的 iPhone 7,它已更新为 iOS 12,但应用程序在尝试启动相机时立即崩溃。
我也尝试过对 int 值进行硬编码:
private void DoTakePictureCommand()
{
var picChooser = Mvx.IoCProvider.Resolve<IMvxPictureChooserTask>();
try
{
picChooser.TakePicture(640, 50, (stream) =>
{
using (var ms = new MemoryStream())
{
stream.CopyToAsync(ms);
ReceiptJpegData = ms.ToArray();
_log.Trace("Picture bytes: {0}", ReceiptJpegData.Length);
InvokeOnMainThread(ImageComplete);
}
}, () =>
{
});
}
catch (Exception e)
{
Debug.Write(e);
}
}
但是结果是一样的
更新
我创建了一个小示例项目来复制该问题。该应用程序同时使用选择图片和拍照 - 仅选择图片作品。我已将其发布到 Github 上的 public 回购:PictureApp
您的问题与您传递的变量有关,请检查它是否不为空且其类型为int
。
_envProvider.Environment.JpegSize,
_envProvider.Environment.JpegQuality,
来自docs:
void TakePicture(int maxPixelDimension, int percentQuality, Action<Stream> pictureAvailable,
Action assumeCancelled);
好的,搞定了!
我会在这里为其他 运行 关注此问题的应用程序开发新手留下一个解决方案。
问题的解决实际上很简单:我所要做的就是添加
<key>NSCameraUsageDescription</key>
<string></string>
至Info.plist。
直到我决定放弃 MvvmCross.Plugin.PictureChooser 并改用 Xam.Plugin.Media,我才收到一条可以理解的错误消息 - 基本上是这样的:"you need to add NSCameraUsageDescription to Info.plist since iOS 10"
我正在开发一个 iOS 应用程序,它需要能够拍照(用来做一些事情)。
我将 Xamarin 与 MvvmCross 6.2.0 一起使用,并导入了 MvxPictureChooser 插件。
我已将 NSPhotoLibraryAddUsageDescription 添加到我的 Info.plist
...
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs to be able to save your expense attachments as images.</string>
<key>UIRequiresFullScreen</key>
<true/>
...
现在,当我尝试使用 ChoosePictureFromLibrary 时,一切顺利。
另一方面,如果我尝试使用 TakePicture(int, int, Action, Action),我会得到一个包含错误的异常:NSInvalidArgumentException 原因:源类型 1 不可用
我的代码如下所示:
private void DoTakePictureCommand()
{
var picChooser = Mvx.IoCProvider.Resolve<IMvxPictureChooserTask>();
try
{
picChooser.TakePicture(_envProvider.Environment.JpegSize, _envProvider.Environment.JpegQuality, (stream) =>
{
using (var ms = new MemoryStream())
{
stream.CopyToAsync(ms);
ReceiptJpegData = ms.ToArray();
_log.Trace("Picture bytes: {0}", ReceiptJpegData.Length);
InvokeOnMainThread(ImageComplete);
}
}, () =>
{
});
}
catch (Exception e)
{
Debug.Write(e);
}
}
完整的错误在这里:
[0:] Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Source type 1 not available Native stack trace:
0 CoreFoundation 0x000000011c41429b __exceptionPreprocess + 331 1 libobjc.A.dylib 0x000000011d2e8735 objc_exception_throw + 48 2 UIKitCore 0x0000000126d03553 -[UIImagePickerController sourceType] + 0 3 xxxiOS 0x000000010ed801b9 xamarin_dyn_objc_msgSend + 217 4 ??? 0x0000000141e58257 0x0 + 5400527447
at ObjCRuntime.Runtime.ThrowNSException (System.IntPtr ns_exception) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/ObjCRuntime/Runtime.cs:398
at ObjCRuntime.Runtime.throw_ns_exception (System.IntPtr exc) [0x00000] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/runtime/Delegates.generated.cs:126
at (wrapper native-to-managed) ObjCRuntime.Runtime.throw_ns_exception(intptr) --- End of stack trace from previous location where exception was thrown --- at (wrapper managed-to-native) ObjCRuntime.Messaging.void_objc_msgSend_Int64(intptr,intptr,long) at UIKit.UIImagePickerController.set_SourceType (UIKit.UIImagePickerControllerSourceType value) [0x00015] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.0.0.15/src/Xamarin.iOS/UIKit/UIImagePickerController.g.cs:587 at MvvmCross.Plugin.PictureChooser.Platforms.Ios.MvxImagePickerTask.TakePicture (System.Int32 maxPixelDimension, System.Int32 percentQuality, System.Action`1[T] pictureAvailable, System.Action assumeCancelled) [0x00014] in <8539a731432e4b45b49dd5ca22de5afd>:0 at xxx.DoTakePictureCommand () [0x0000d] in C:\Users\xxxx\Documents\IdeaProjects\xxxx\xxxx\XXX.Core\ViewModels\AddExpenseViewModel.cs:447 0 CoreFoundation 0x000000011c41429b __exceptionPreprocess + 331 1 libobjc.A.dylib 0x000000011d2e8735 objc_exception_throw + 48 2 UIKitCore
0x0000000126d03553 -[UIImagePickerController sourceType] + 0 3
xxxiOS 0x000000010ed801b9 xamarin_dyn_objc_msgSend + 217 4 ???
0x0000000141e58257 0x0 + 5400527447 2018-09-27 23:15:03.294036+0200 xxxiOS[46563:4418172] 2018-09-27 11:15:03 [TRACE] (MvvmCross.Logging.MvxLog) iOSNavigation 2018-09-27 23:15:03.294886+0200 xxxiOS[46563:4418172] 2018-09-27 11:15:03 [TRACE] (MvvmCross.Logging.MvxLog) PresentationAttribute not found for AddExpenseView. Assuming animated Child presentation CalabashServer | XTC_SKIP_LPSERVER_TOKEN is not in the app environment CalabashServer | Will start LPServer with identifier: c36c12ce937d044d55d0c208f9d4502868233513
更新
我现在已经尝试将代码部署到我的 iPhone 7,它已更新为 iOS 12,但应用程序在尝试启动相机时立即崩溃。
我也尝试过对 int 值进行硬编码:
private void DoTakePictureCommand()
{
var picChooser = Mvx.IoCProvider.Resolve<IMvxPictureChooserTask>();
try
{
picChooser.TakePicture(640, 50, (stream) =>
{
using (var ms = new MemoryStream())
{
stream.CopyToAsync(ms);
ReceiptJpegData = ms.ToArray();
_log.Trace("Picture bytes: {0}", ReceiptJpegData.Length);
InvokeOnMainThread(ImageComplete);
}
}, () =>
{
});
}
catch (Exception e)
{
Debug.Write(e);
}
}
但是结果是一样的
更新
我创建了一个小示例项目来复制该问题。该应用程序同时使用选择图片和拍照 - 仅选择图片作品。我已将其发布到 Github 上的 public 回购:PictureApp
您的问题与您传递的变量有关,请检查它是否不为空且其类型为int
。
_envProvider.Environment.JpegSize,
_envProvider.Environment.JpegQuality,
来自docs:
void TakePicture(int maxPixelDimension, int percentQuality, Action<Stream> pictureAvailable,
Action assumeCancelled);
好的,搞定了!
我会在这里为其他 运行 关注此问题的应用程序开发新手留下一个解决方案。
问题的解决实际上很简单:我所要做的就是添加
<key>NSCameraUsageDescription</key>
<string></string>
至Info.plist。
直到我决定放弃 MvvmCross.Plugin.PictureChooser 并改用 Xam.Plugin.Media,我才收到一条可以理解的错误消息 - 基本上是这样的:"you need to add NSCameraUsageDescription to Info.plist since iOS 10"