我想通过 Rococoa 访问 Java 中的 Objective-C EKEventStore。API 指定了一个回调,以便在用户接受日历访问提示时获得通知,这在纯 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-Crash。
编辑2:
现在我正在使用 Rococoa.proxy(handler) 函数进行回调,就像在 Rococoa 库中一样。出现输入提示,但未调用回调函数。我认为我的回调初始化仍然是错误的。