在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:BlueRiverInteractive/robovm-ios-bindings开源软件地址:https://github.com/BlueRiverInteractive/robovm-ios-bindings开源编程语言:Objective-C 78.8%开源软件介绍:RoboVM iOS BindingsRoboPodsNOTE: These bindings are going to be deprecated in favor ofA collection of third party bindings for RoboVM iOS. How do I use these bindings?
How do I use these bindings with LibGDX 1.x?
Those bindings will now be available within your project as needed. Be sure to download updated JAR files at regular intervals if you want the latest updates. How do I create a binding?When you want to create a binding, you should have a basic knowledge of the syntax of Objective-C. Also it wouldn’t hurt if you know how to use Xcode and how static libraries work. Analyzing the framework or SDKFirst of all, let’s get the AdMob iOS SDK from here: https://developers.google.com/mobile-ads-sdk/download#downloadios. Creating a binding projectNow that you have the necessary files and information, you can start creating the binding project. Please always adopt the RoboVM bindings namespace for consistency:
The app name becomes „Admob Sample“ and the app id just „admob“. Open up the newly created project and add the missing packages and the Sample class. package org.robovm.bindings.admob.sample;
import org.robovm.apple.foundation.NSAutoreleasePool;
import org.robovm.apple.uikit.UIApplication;
import org.robovm.apple.uikit.UIApplicationDelegateAdapter;
public class Sample extends UIApplicationDelegateAdapter {
@Override
public void didFinishLaunching (UIApplication application) {
}
public static void main (String[] argv) {
try (NSAutoreleasePool pool = new NSAutoreleasePool()) {
UIApplication.main(argv, null, Sample.class);
}
}
} Copy the library archive file (*.a) into the libs folder of your binding project. Now we are ready to create the bindings! Binding classesFirst of all we will create a Java class for every Objective-C interface. Typically this is one class per header file.
In our case this will be:
Create those classes inside the Example GADBannerView: @NativeClass
public class GADBannerView extends UIView {
} HINT: If you are binding Cocoa or CocoaTouch frameworks you should add the @Library("CoreTelephony")
@NativeClass
public class CTCallCenter extends NSObject {
} Binding methodsLet’s dive deeper into the header file of GADBannerView. Open the file in Eclipse.
The information we need here starts after the line with You can remove the
For example, let’s bind this method: - (void)loadRequest:(GADRequest *)request; This method is an instance method ( In RoboVM we can bind this method like this: @Method(selector = "loadRequest:")
public native void loadRequest(GADRequest request); Congratulations! You have now successfully bound your first method. The selector name can be multiple parts long. In the following example the selector is marked bold:
Use Java Bean naming conventions for consistency. Shorten long method names. The example above in Java would be: @Method(selector = "setLocationWithLatitude:longitude:accuracy:")
public native void setLocation(float latitude, float longitude, float accuracyInMeters); Don't forget to add the static keyword for methods starting with a /// Creates an autoreleased GADRequest.
+ (instancetype)request; becomes @Method(selector = "request")
public static native GADRequest request(); Binding constructorsConstructors can be identified because of their - (id)initWithAdSize:(GADAdSize)size; You can bind this constructor like any other method but need to use the return type @Method(selector = "initWithAdSize:")
private native @Pointer long init(GADAdSize size); Make that method private because we don’t want anyone to manually init the object. public GADBannerView(GADAdSize size) {
super((SkipInit)null);
initObject(init(size));
} Note the super constructor call. This is necessary because otherwise Java would also call the default constructor and initialize our Objective-C object twice. Binding propertiesLet’s bind the following property: @property(nonatomic, copy) NSString *adUnitID; The selector of this property is @Property(selector = "adUnitID")
public native String getAdUnitID ();
@Property(selector = "setAdUnitID:")
public native void setAdUnitID (String id); Note that we add There are a few things we need to keep an eye on: @property(nonatomic, readonly) BOOL hasAutoRefreshed; We can only create a getter for this, as it has the readonly modifier. @property(nonatomic, assign) NSObject<GADBannerViewDelegate> *delegate When binding delegate properties or other weak/assign properties, we need to retain a strong reference of them, otherwise we will get memory issues and app crashes: @Property(selector = "delegate")
public native GADBannerViewDelegate getDelegate();
@Property(selector = "setDelegate:", strongRef = true)
public native void setDelegate(GADBannerViewDelegate delegate); HINT: You can leave out the selector parameter, if you name the property methods with getProperty/isProperty and setProperty. The example above would still work, if we hadn’t specified the selector parameter of the annotations. Binding delegatesTo be done… Binding blocksObj-C blocks can be compared to Java listeners with just one method. A typical example of this is the Runnable class. These blocks can occur in two forms: As a custom type: typedef void (^FBAppCallHandler)(FBAppCall *call);
+ (BOOL)handleOpenURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
fallbackHandler:(FBAppCallHandler)handler; Or inline of an Obj-C method: + (BOOL)handleOpenURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
fallbackHandler:(void(^)(FBAppCall *call))handler; In any way, you can identify them by the There are two ways in Java to bind a block type: Inline: @Method(selector = "handleOpenURL:sourceApplication:fallbackHandler:")
public static native boolean handleOpenURL(NSURL url, String sourceApplication, @Block VoidBlock1<FBAppCall> handler); The
Custom Type: public interface FBAppCallHandler {
void invoke(FBAppCall call);
}
@Method(selector = "handleOpenURL:sourceApplication:fallbackHandler:")
public static native boolean handleOpenURL(NSURL url, String sourceApplication, @Block FBAppCallHandler handler); You create a custom interface with exactly one function. The function must have the exact return type and parameters as the Obj-C block. This approach is slightly more work but gives you better readability, as you can name your block and parameters. Both of these approaches apply two both forms of Obj-C blocks. HINT: If you need to define a void block with no parameter, you can just use Binding structsTo be done... Binding C functionsTo be done... Binding enumsIn Objective-C there are typically two ways to define enums. typedef NS_ENUM(NSInteger, GADGender) {
kGADGenderUnknown, ///< Unknown gender.
kGADGenderMale, ///< Male gender.
kGADGenderFemale ///< Female gender.
}; This is actually the same as: typedef enum {
kGADGenderUnknown, ///< Unknown gender.
kGADGenderMale, ///< Male gender.
kGADGenderFemale ///< Female gender.
} GADGender; We can bind this as a Java valued enum: public enum GADGender implements ValuedEnum {
Unknown(0),
Male(1),
Female(2);
private final long n;
private GADGender (long n) {
this.n = n;
}
@Override
public long value () {
return n;
}
} The names of the enum constants is unimportant but the order and value is not. It can happen that some enum constants have the same value as other constants in Objective-C, thus they need to have the same value in Java. kGADExampleEmpty = 0,
kGADExampleFalse,
kGADExampleTrue,
kGADExampleError = kGADExampleFalse,
kGADExampleNetworkError = 1 | (1 << 9) In Java: Empty(0),
False(1),
True(2),
Error(1),
NetworkError(1 | (1 << 9)) Don't be scared if you find an enum without any name: enum {
kGADExampleTypeFirst,
kGADExampleTypeSecond
}; Just invent a proper enum name: public enum GADExampleType implements ValuedEnum {
...
} Binding bitmasksTo be done… Binding global valuesGlobal values in Obj-C can be identified by the extern GADAdSize const kGADAdSizeBanner; The name of this global value is @GlobalValue(symbol = "kGADAdSizeBanner", optional=true)
public static native @ByVal GADAdSize Banner(); Global values are always static and can have any name you want. The @ByVal annotation is only needed for struct types as explained in the structs section. Binding constantsC constants are identified by the #define PI 3.14159265359 public static final long PI = 3.14159265359; HINT: You can also define enums as constants. This is especially useful if the enum has just one entry. Finishing the bindingTo be done… robovm.xml... reference to integration instructions above... Creating a static library in XcodeTo be done… Pull requestsWhen you submit a binding as a pull request be sure to use the following namespace:
Also please try to use Java naming conventions were applicable. For example: typedef enum FBErrorCode {
FBErrorInvalid = 0,
FBErrorOperationCancelled,
} FBErrorCode; becomes: public enum FBErrorCode implements ValuedEnum {
Invalid(0),
OperationCancelled(1);
private final long n;
private FBErrorCode (long n) {
this.n = n;
}
@Override
public long value () {
return n;
}
} |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论