Applifier API には次のバインディングがあります。
namespace MonoTouch.Applifier {
[BaseType (typeof (NSObject))]
interface Applifier {
[Export ("initWithApplifierID:withWindow:supportedOrientations:"), Static]
Applifier InitWithApplifierId (string applifierId, UIWindow withWindow,
UIDeviceOrientation firstOrientation, IntPtr orientationsPtr);
[Export ("initWithApplifierID:withWindow:delegate:usingBanners:usingInterstitials:usingFeaturedGames:supportedOrientations:"), Static]
Applifier InitWithApplifierId (string applifierId, UIWindow withWindow,
ApplifierGameDelegate gameDelegate, bool usingBanners, bool usingInterstitials,
bool usingFeaturedGames, UIDeviceOrientation firstOrientation, IntPtr orientationsPtr);
[Export ("sharedInstance"), Static]
Applifier SharedInstance { get; }
[Wrap ("WeakDelegate")]
ApplifierGameDelegate Delegate { get; set; }
[Export ("gameDelegate", ArgumentSemantic.Retain)]
NSObject WeakDelegate { get; set; }
[Export ("prepareFeaturedGames")]
void PrepareFeaturedGames ();
[Export ("showFeaturedGames")]
void ShowFeaturedGames ();
[Export ("showBannerAt:")]
void ShowBannerAt (PointF position);
}
[BaseType (typeof (NSObject))]
[Model]
interface ApplifierGameDelegate {
[Export("applifierInterstitialReady"), Abstract]
void InterstitialReady ();
[Export("applifierFeaturedGamesReady"), Abstract]
void FeaturedGamesReady ();
[Export("applifierBannerReady")]
void BannerReady ();
[Export("applifierAnimatedReady")]
void AnimatedReady ();
[Export("applifierCustomInterstitialReady")]
void CustomInterstitialReady ();
[Export("pauseGame")]
void PauseGame ();
[Export("resumeGame")]
void ResultGame ();
}
}
There are two methods in my extras C# file that make calling those init methods a little easier. I don't think they're relevant here, but I can include them if needed.
Here's the Obj-C declaration of "gameDelegate":
@property (nonatomic, retain) id<ApplifierGameDelegate> gameDelegate;
And the protocol definition of ApplifierGameDelegate:
@protocol ApplifierGameDelegate <NSObject>
- (void)applifierInterstitialReady;
- (void)applifierFeaturedGamesReady;
@optional
- (void)applifierBannerReady;
- (void)applifierAnimatedReady;
- (void)applifierCustomInterstitialReady;
- (void)pauseGame;
- (void)resumeGame;
@end
The problem here is that no matter what I try, I can't get the methods on my delegate implementation in my monotouch project to get callbacks from Applifier. Some notes:
I have a very simple example app in Xcode following the applifier tutorial that does work (the test case is that when the featured games are shown, the "pauseGame" method gets called on the delegate)
- I have noticed that if I assign any object to WeakDelegate, nothing complains, which surprised the heck out of me. For instance, no errors or warnings with: Applifier.SharedInstance.WeakDelegate = new NSString("Foo");
- I can fetch the delegate from the shared instance and call the method myself and it does get called. For instance: Applifier.SharedInstance.Delegate.PauseGame(); -- This holds true whether I assign my delegate instance to WeakDelegate, Delegate, or via the init method that accepts the delegate as one of the parameters.
My only conclusion right now is that it seems like two things are true:
- I can assign any object to gameDelegate through the binding, and nothing complains
- Something somewhere is failing to recognize that my ApplifierGameDelegate interface matches up with the AppliferGameDelegate protocol.
The only other weird thing I've noticed is that in all the other example bindings I've poked around in in the monotouch-bindings git project, I haven't seen any others that use the retain property on a delegate property.
My fork of monotouch-bindings can be found at https://github.com/threerings/monotouch-bindings. The current HEAD is a hacked together workaround that gets what we need done, but I'd still like to end up with a full proper binding (just need the delegate to work from C# land). The original binding that I was writing about in this question can be viewed at commit fdcff4662a36ac42fbe135c098ff7f71cbdf205d.