ASIHTTPRequest Monotouch Binding Callback/Event - binding

I am trying to wrap ASIHTTPRequest objective-c library to monotouch and I am stuck on .
The objective-c header file contains
#property (assign) SEL requestDidFinishSelector;
and when I use monotouch binding generator it generates
[Export ("requestDidStartSelector")]
Selector RequestDidStartSelector { get; set; }
This compiles successfully but it does not get called. I want to be able to do
networkQueue.RequestDidFinish += HandleRequestFinish;
from my C# code.
Does anyone already have ASIHTTPRequest monotouch binding or guide me on how to hook up callback events?
Thanks.

The selector will only return the handle to the "selector" that you can use.
What you need to do is write your event handler more or less like this:
class MyCallbacker {
public MyCallbacker (Action t) { this.t = t; }
[Preserve (Conditional=true)]
[Export ("MyCallBack")]
void Callback () {
t ();
}
}
event RequestDidFinish {
add {
requestDidFinishSelector = new Selector ("MyCallback");
new MyCallbacker (() => value);
}
}

Related

NSItemProviderReading on Xamarin

To do files drag & drop for files in iOS 11 you need to implement NSItemProviderReading, there is the sample code for swift here: iOS 11 dropInteraction performDrop for files
However, how to do that in Xamarin, I guess the class definition should look like this, but how to implement the methods?
public class DocumentProvider : NSObject, INSItemProviderReading
{
}
You can implement the NSItemProviderReading like this:
class MyItemProvider : UIView, INSItemProviderReading {
[Export ("readableTypeIdentifiersForItemProvider")]
public static string [] ReadableTypeIdentifiersForItemProvider => new string [] { "public.image", "public.data" }
[Export ("objectWithItemProviderData:typeIdentifier:error:")]
public static MyItemProvider GetObject (NSData data, string typeIdentifier, out NSError outError)
{
outError = null;
switch (typeIdentifier) {
case "public.image": return new ...;
case "public.data": return new ...;
default:
outError = new NSError (...);
return null;
}
}
}
Reference:NSItemProviderReading requirements.

MvvmLight unable to create a controller for key

I am designing a cross platform application architecture using Xamarin iOS and Xamarin Android I decided to go with MvvmLight, it looks descent and is not hiding everything from the MVVM pattern, good and flexible.
While everything started to make sense trying to set it up and learn how to use it, I find myself difficult to understand why I get the following error.
Unable to create a controller for key ChartsPage
The setup.
In a PCL I have my ViewModels. I have a ViewModelLocator setup. I use the mvvmlightlibs Nuget Package.
public class ViewModelLocator
{
public static readonly string SchedulerPageKey = #"SchedulerPage";
public static readonly string ChartsPageKey = #"ChartsPage";
[SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public SchedulerViewModel Scheduler
{
get
{
return ServiceLocator.Current.GetInstance<SchedulerViewModel>();
}
}
public BizchartsViewModel Bizcharts
{
get
{
return ServiceLocator.Current.GetInstance<BizchartsViewModel>();
}
}
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
// Haven't declared something yet
}
else
{
// Haven't declared something yet
}
SimpleIoc.Default.Register<SchedulerViewModel>();
SimpleIoc.Default.Register<BizchartsViewModel>();
}
}
The I have a unified iOS application using universal storyboard with size classes which has an initial UINavigationViewController SchedulerViewController and in the ViewDidLoad method I test the navigation to BizchartsViewController with 3 seconds delay. After 3 seconds I get the exceptions.
In the AppDelegate.
private static ViewModelLocator _locator;
public static ViewModelLocator Locator
{
get
{
if (_locator == null)
{
SimpleIoc.Default.Register<IDialogService, DialogService>();
_locator = new ViewModelLocator();
}
return _locator;
}
}
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
var nav = new NavigationService();
nav.Initialize((UINavigationController)Window.RootViewController);
nav.Configure(ViewModelLocator.ChartsPageKey, typeof(BizchartsViewController));
SimpleIoc.Default.Register<INavigationService>(() => nav);
return true;
}
The SchedulerViewController.
partial class SchedulerViewController : UIViewController
{
public SchedulerViewModel Vm {
get;
private set;
}
public SchedulerViewController (IntPtr handle) : base (handle)
{
Vm = AppDelegate.Locator.Scheduler;
}
public async override void ViewDidLoad ()
{
base.ViewDidLoad ();
await Task.Delay (3000);
Vm.NavigateToCharts ();
}
}
The SchedulerViewModel.
public class SchedulerViewModel : ViewModelBase
{
public void NavigateToCharts()
{
var nav = ServiceLocator.Current.GetInstance<INavigationService>();
nav.NavigateTo(ViewModelLocator.ChartsPageKey);
}
}
I definitely miss a detail somewhere!!!
If you follow carefully the blog post here, it says that with Storyboard you should use the string overload and not the typeof() in nav.Configure(Key, ViewController) and always set the storyboardId and restorationId in the Storyboard ViewController.
Note that because we are using a Storyboard, you must make sure to use
the Configure(string, string) overload, and NOT the Configure(string,
Type) one.

Access a Xamarin Component's buttons (specifically the iOS card.io component)

The card.io component (http://components.xamarin.com/view/cardioios) has a fallback screen that has a Cancel and a Done button on them.
Neither of which actually do anything. I assume it is up to me to subscribe to and event, however, there is no event to subscribe to.
Here is the code:
var paymentDelegate = new PaymentViewControllerDelegate();
var paymentViewController = new Card.IO.PaymentViewController(paymentDelegate);
paymentDelegate.OnScanCompleted += (viewController, cardInfo) =>
{
viewController.DismissViewController(true, null);
if (cardInfo == null)
{
}
else
{
new UIAlertView("Card Scanned!", cardInfo.CardNumber, null, "OK", null).Show();
}
};
paymentViewController.AppToken = "app-token";
// Display the card.io interface
base.PresentViewController(paymentViewController, true, () => { });
There is a method on the PaymentViewControllerDelegate, but I can't figure out what to do with it:
public override void UserDidCancel(PaymentViewController paymentViewController);
public override void UserDidProvideCreditCardInfo(CreditCardInfo cardInfo, PaymentViewController paymentViewController);
I guess the problem is that the Component doesn't expose any events for the Fallback View.
You need to subclass PaymentViewControllerDelegate:
public class MyPaymentDelegate : PaymentViewControllerDelegate
{
public MyPaymentDelegate ()
{
}
public override void UserDidCancel (PaymentViewController paymentViewController)
{
// Implement on-cancel logic here...
base.UserDidCancel (paymentViewController);
}
public override void UserDidProvideCreditCardInfo (CreditCardInfo cardInfo, PaymentViewController paymentViewController)
{
// Implement logic for credit card info provided here...
base.UserDidProvideCreditCardInfo (cardInfo, paymentViewController);
}
}
And then provide an instance of this class into the constructor for Card.IO.PaymentViewController:
var paymentDelegate = new MyPaymentDelegate();
var paymentViewController = new Card.IO.PaymentViewController(paymentDelegate);
So, I figured this out by looking at the working sample application and comparing it to what I had done.
All I had to do was widen the scope of the paymentDelegate and paymentViewController variables.
If you look at the sample, you really just need to subscribe to the OnScanCompleted event which is called in both cases of UserDidCancel (where cardInfo will be null), and UserDidProvideCreditCardInfo (where it will not be null).
In fact, this is the code for the binding, so you can see the Event was made as a 'helper' to make it so you didn't have to make your own delegate implementation:
namespace Card.IO
{
public partial class PaymentViewControllerDelegate : BasePaymentViewControllerDelegate
{
public delegate void ScanCompleted(PaymentViewController viewController, CreditCardInfo cardInfo);
public event ScanCompleted OnScanCompleted;
public override void UserDidCancel (PaymentViewController paymentViewController)
{
var evt = OnScanCompleted;
if (evt != null)
evt(paymentViewController, null);
}
public override void UserDidProvideCreditCardInfo (CreditCardInfo cardInfo, PaymentViewController paymentViewController)
{
var evt = OnScanCompleted;
if (evt != null)
evt(paymentViewController, cardInfo);
}
}
}
If you still really want to implement the delegate yourself, subclass BasePaymentViewController instead, however I don't think you really need to make your own subclass of it...
Hopefully that helps!

Accessing public variables from inside ccTouchesBegan method in cocos2d-x

I'm having little trouble accessing public ivars form the ccTouchesBegan method,
I have this Scene:
class introScene : public cocos2d::CCLayer {
public:
virtual bool init();
static cocos2d::CCScene* scene();
bool autoScroll;
virtual void ccTouchesBegan(cocos2d::CCSet* touches, cocos2d::CCEvent* event);
void skip();
CREATE_FUNC(introScene);
};
and from inside the .cpp file I try to access the variable autoScroll, but it insists that the variable doesn't exist, am I doing anything wrong here ??
void ccTouchesBegan(cocos2d::CCSet* touches, cocos2d::CCEvent* event){
autoScroll = false;
}
This generates: use of undeclared identifier 'autoScroll'
I don't know anything about cocos2d, but I reckon you've defined the method incorrectly as you've missed off the class name. Try this:
void introScene::ccTouchesBegan(cocos2d::CCSet* touches, cocos2d::CCEvent* event){
// ^^^^^^^
autoScroll = false;
}

How can i call dynamic object like a function?

I am studying orchard architecture.i have faced with a strange concept in display management section.
in Partial view page there is a 'function call like' syntax like so Display(Model.Head). that is not a function thought, it is a dynamic object defined in orchard WebViewPage.
I am wondering how to define a dynamic object so that you can call it (and pass it an argument as well) like a function as i mentioned.
thanks in advance.
A lighter weight way to do it without clay would be to subclass the built-in DynamicObject class.
public static dynamic Display;
void Main()
{
Display = new MyCallableObject();
//this is what i was after
Console.Write(Display("bla bla bla"));
}
public class MyCallableObject:DynamicObject
{
public override bool TryInvoke(InvokeBinder binder, object[] args, out Object result)
{
result = string.Format("This is response for {0}",args.FirstOrDefault());
return true;
}
}
I finally found it my self!
all the operations have done with Clay Library behind the scene.i have wrote a sample console app for demonstrating the process.
class Program
{
static void Main(string[] args)
{
Display = ClayActivator.CreateInstance<MyResponser>(new List<IClayBehavior> {new MyFunctionCallBehavior()});
//this is what i was after
Console.Write(Display("bla bla bla"));
}
public static dynamic Display;
}
public class MyFunctionCallBehavior : IClayBehavior
{
public object InvokeMember(Func<object> proceed, object self, string name, INamedEnumerable<object> args)
{
return ((MyResponser)self).ResponseForRequest(args.FirstOrDefault().ToString());
}
}
public class MyResponser
{
public string ResponseForRequest(string param)
{
return string.Format("This is response for {0}",param);
}
}

Resources