java - JNA Objective-C (Rococoa) 日历回调

标签 java objective-c jna ekeventkit rococoa

我想通过 Rococoa 访问 Java 中的 Objective-C EKEventStore。 API 指定 callback当用户接受日历访问提示时收到通知,这在纯 Objective-C 中完美运行。

    Native.loadLibrary("EventKit", EventKitLibrary.class);

    EKEventStore store = EKEventStore.CLASS.alloc();
    store.init();
    //store = store.initWithAccessToEntityTypes(EKEntityType.EKEntityTypeEvent); // no notification
    EKEventStoreRequestAccessCompletionHandler handler = new EKEventStoreRequestAccessCompletionHandler() {
        @Override
        public void invoke(boolean granted, Pointer error) {
            System.out.println("Access: " + granted);
            NSArray calArray = store.calendarsForEntityType(EKEntityType.EKEntityTypeEvent);
            for (int i = 0; i < calArray.count(); i++) {
                NSObject calObject = calArray.objectAtIndex(i);
                EKCalendar osxcal = Rococoa.cast(calObject, EKCalendar.class);
                System.out.println(osxcal.title().toString());
            }
        }

    };
    ObjCObject object = Rococoa.proxy(handler); // get Objective C Callback Object to send
    store.requestAccessToEntityType_completion(EKEntityType.EKEntityTypeEvent, object.id());

    try {
        Thread.sleep(10000); // wait for the access prompt
    } catch (InterruptedException ex) {
    }

    // random object access to save instances from gc
    System.out.println(handler.toString());
    System.out.println(store.id());
    System.out.println(object.id());

图书馆

public interface EventKitLibrary extends Library {

    public static EventKitLibrary INSTANCE = (EventKitLibrary) Native.loadLibrary("EventKit", EventKitLibrary.class);

}

映射的类

public abstract class EKEventStore extends NSObject {

    public static final _Class CLASS = Rococoa.createClass("EKEventStore", _Class.class);

    public interface _Class extends ObjCClass {

        public abstract EKEventStore alloc();
    }

    public static interface EKEntityType {

        public static final int EKEntityTypeEvent = 0;
        public static final int EKEntityTypeReminder = 1;
    };

    public static interface EKEntityMask {

        public static final int EKEntityMaskEvent = (1 << EKEntityType.EKEntityTypeEvent);
        public static final int EKEntityMaskReminder = (1 << EKEntityType.EKEntityTypeReminder);
    };

    public abstract EKEventStore initWithAccessToEntityTypes(int EKEntityMask);

    public abstract EKEventStore init();

    public abstract void requestAccessToEntityType_completion(int EKEntityType, ID handler);

    interface EKEventStoreRequestAccessCompletionHandler {

        void invoke(boolean granted, Pointer error);
    }

    public abstract NSArray calendarsForEntityType(int EKEntityType);
}


public abstract class EKCalendar extends NSObject {

    public static final _Class CLASS = Rococoa.createClass("EKCalendar", _Class.class);

    public static interface _Class extends ObjCClass {

        public NSObject alloc();
    }

    public abstract NSString title();
}

我只因为 NSError 参数缺少类型转换而收到 IllegalArgumentException。我做错了什么,还是应该实现 TypeConverter?如果,我该怎么做?

编辑:

现在我使用 Pointer 而不是 NSError 作为回调函数的参数,并且出现以下 JVM 崩溃。

编辑2:

现在我使用 Rococoa.proxy(handler) 函数进行回调,就像在 Rococoa 库中一样。出现输入提示,但没有调用回调函数。我认为我的回调初始化仍然是错误的。

最佳答案

通常,TypeMapper 是这样实现的,它将 Pointer native 类型转换为其他 Java 类型:

class NSErrorTypeMapper extends DefaultTypeMapper {
    public NSErrorTypeMapper() {
        TypeConverter tc = new TypeConverter() {
            public Object toNative(Object value, ToNativeContext ctxt) {
                Pointer p = // convert your NSError "value" into a Pointer
                return p;
            }
            public Object fromNative(Object value, FromNativeContext ctxt) {
                Pointer p = (Pointer)value;
                Object object = // convert the pointer into an NSError object
                return object;    
            }
            public class nativeType() {
                return Pointer.class;
            }
        };
        addToNativeConverter(NSError.class, tc);
        addFromNativeConverter(NSError.class, tc);
    }
}

关于java - JNA Objective-C (Rococoa) 日历回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32386391/

相关文章:

java - 复制 InputStream,如果大小超过限制则中止操作

iphone - 将 ASIHttpRequest PDF 存储为 NSData

objective-c - Mac 应用程序中的 Facebook

java - 如何使用 Java/JNA 在 Vista+ 上以提升的权限启动应用程序以触发 UAC

java - 获取 mylyn 源代码

java - 哪种 OOP 方法适合周期表属性?

java - 使用父类(super class)作为引用而不是子类?

ios - 设置多个排序描述符

java - 如何使用 JNA 传递结构数组

java - 如何使用 java 实现类似 alt+tab 的功能?