[英]How can I use a method that is not exposed by Xamarin on iOS?
I want to use a method that exists on NSString
that is called writeToFile:atomically:encoding:error:
but this method is not exposed to Xamarin.iOS . 我想使用NSString
上存在的一个名为writeToFile:atomically:encoding:error:
但是这个方法没有暴露给Xamarin.iOS 。
How can I create a binding that will allow me to use this method? 如何创建允许我使用此方法的绑定? All resources that I found explain how to bind libraries. 我找到的所有资源都解释了如何绑定库。
I am aware there are better ways to write a string to a file but so it is not so much about this method but rather how to bind such methods. 我知道有更好的方法可以将字符串写入文件,但这不是关于这个方法,而是如何绑定这些方法。
So at the end I have managed to solve it through a binding library. 所以最后我设法通过绑定库来解决它。
I have created a new project of type "Binding Library (iOS)". 我创建了一个类型为“绑定库(iOS)”的新项目。 After that I added a new file NSStringWriteToFileExtension.cs
and in Properties I made sure the Build Action is set to ObjcBindingApiDefinition
and put the following code in there. 之后我添加了一个新文件NSStringWriteToFileExtension.cs
,在属性中我确保将Build Action设置为ObjcBindingApiDefinition
并将以下代码放在那里。
using Foundation;
using ObjCRuntime;
namespace Foundation
{
[Category]
[BaseType(typeof(NSString))]
public interface NSStringWriteToFileExtension
{
[Export("writeToFile:atomically:encoding:error:")]
bool Write(string filePath, bool atomically, NSStringEncoding encoding, out NSError error);
}
}
This creates a new extension on NSString
that gives me access to the method. 这将在NSString
上创建一个新的扩展,使我可以访问该方法。
Calling a method on an ObjC instance is about messaging. 在ObjC实例上调用方法是关于消息传递。 You do not directly invoke the method, but the ObjC objc_msgSend
function will when called with the object to invoke it upon, the selector which describes the method to be invoked, and the parameters of the method. 您不直接调用该方法,但ObjC objc_msgSend
函数将在调用对象时调用它,描述要调用的方法的选择器以及方法的参数。
objc_msgSend
entry point: 定义objc_msgSend
入口点: Note: This includes the object that you wish to invoke the selector on, the selector created with the selector's name, and then the parameters to be passed 注意:这包括您希望调用选择器的对象,使用选择器名称创建的选择器,然后是要传递的参数
// NSString writeToFile:atomically:encoding:error:
[DllImport(Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
static extern bool NSString_bool_obj_msgSend_IntPtr_bool_NSStringEncoding_IntPtr(
IntPtr target,
IntPtr selector,
IntPtr path,
bool atomically,
NSStringEncoding encoding,
IntPtr error
);
Note: Cache this if you will be calling it repeatedly 注意:如果您要反复调用它,请缓存此项
var nsStringWriteToFileSelector = new Selector("writeToFile:atomically:encoding:error:");
// Selector for NSString writeToFile:atomically:encoding:error:
var nsStringWriteToFileSelector = new Selector("writeToFile:atomically:encoding:error:");
// Parameters to be passed via `objc_msgSend`
var nsString = new NSString("StackOverflow");
var path = new NSString("nsstring.txt");
var error = new NSError();
// Call objc_msgSend with the object, selector and parameters
var success = NSString_bool_obj_msgSend_IntPtr_bool_NSStringEncoding_IntPtr(
nsString.Handle,
nsStringWriteToFileSelector.Handle,
path.Handle,
true,
NSStringEncoding.UTF8,
error.Handle);
if (success && File.Exists(path.ToString()))
Console.WriteLine("success");
else
Console.WriteLine(error.Description);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.