If I have the following ( a protocol and then an interface which uses that protocol), what is the correct way to set up the ApiDefinition for btouch? I've got most of the .h file converted but this one is tricking me up.
Thanks
Jeff
#protocol GRGrabbaPreferencesProtocol <NSObject>
- (NSString*) baseNamepace;
#end
#interface GRGrabbaPreferences : NSObject <GRGrabbaPreferencesProtocol>
{
GRGrabbaBarcodePrefs *barcode;
}
#property (retain) GRGrabbaBarcodePrefs *barcode;
#end
#interface GRGrabbaBarcodePrefs : NSObject <GRGrabbaPreferencesProtocol>
#end
Protocols are really just inlined into your interface, so you can either merely inline the properties directly into your class, or you can have the generator inline those for you.
// Notice the lack of [BaseType] attribute on this one
interface GRGrabbaPreferencesProtocol {
[Export ("baseName")]
string BaseName { get; }
}
[BaseType (typeof (NSObject))]
interface GRGrabbaPreferences : GRGrabbaPreferencesProtocol {
[Export ("barcode")]
GRGrabbaBarcodePrefs Barcode { get; }
}
[BaseType (typeof (NSObject))]
interface GRGrabbaBarcodePrefs : GRGrabbaPreferencesProtocol {
}
The above is identical to:
[BaseType (typeof (NSObject))]
interface GRGrabbaPreferences : GRGrabbaPreferencesProtocol {
[Export ("baseName")]
string BaseName { get; }
[Export ("barcode")]
GRGrabbaBarcodePrefs Barcode { get; }
}
[BaseType (typeof (NSObject))]
interface GRGrabbaBarcodePrefs : GRGrabbaPreferencesProtocol {
[Export ("baseName")]
string BaseName { get; }
}
It is more practical to let the generator take over the inlining to avoid errors and cut/paste problems. But notice that no GRGrabbaPreferencesProtocol is exported to C# in any form.
Related
I have following code snipped and I tried to test it using typemock but got InvalidCast exception. ISomeClass is just an interface and SomeClass implements that interface. UseOfSomeClass is another class which uses SomeClass and its constructor takes SomeClass as parameter. I need to test UseOfSomeClass. How do I inject a typemock fake object into a class constructor?
public interface ISomeClass
{
void DoSomething();
}
public class SomeClass : ISomeClass
{
public void DoSomething()
{
Console.WriteLine("Do something!");
}
}
public class UseOfSomeClass
{
public SomeClass SomeClassProperty { get; set; }
public bool IsChecked { get; set; }
public UseOfSomeClass(SomeClass someClass)
{
SomeClassProperty = someClass;
}
public void MyMethod()
{
SomeClassProperty.DoSomething();
IsChecked = true;
}
}
Then test:
[TestClass]
public class UseOfSomeClassTest
{
[TestMethod]
public void TestMethod1()
{
var fakeSomeClass = Isolate.Fake.Instance<ISomeClass>();
var use = new UseOfSomeClass((SomeClass)fakeSomeClass);
use.MyMethod();
Assert.IsTrue(use.IsChecked);
}
}
Thanks!
Typemock Isolator allows you to mock concrete classes, so there's no need to fake ISomeClass in your test case. You can just fake SomeClass and send it as a parameter to the ctor.
[TestMethod, Isolated]
public void TestMethod1()
{
var fakeSomeClass = Isolate.Fake.Instance<SomeClass>();
var use = new UseOfSomeClass(fakeSomeClass);
use.MyMethod();
Assert.IsTrue(use.IsChecked);
}
i have a class that binds a obj-c object
public unsafe partial class CUSTOMER_INFO : NSObject {
[Export ("signature", ArgumentSemantic.Retain)]
get {
NSData ret;
if (IsDirectBinding) {
ret = Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, Selector.GetHandle ("signature")));
} else {
ret = Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("signature")));
}
if (!IsNewRefcountEnabled ())
__mt_Signature_var = ret;
return ret;
}
[Export ("setSignature:", ArgumentSemantic.Retain)]
set {
if (value == null)
throw new ArgumentNullException ("value");
if (IsDirectBinding) {
global::ApiDefinition.Messaging.void_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle ("setSignature:"), value.Handle);
} else {
global::ApiDefinition.Messaging.void_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle ("setSignature:"), value.Handle);
}
if (!IsNewRefcountEnabled ())
__mt_Signature_var = value;
}
}
but when i declare it and i pass it to a method (inside a ios binding library), i get the known exception
System.ExecutionEngineException: Attempting to JIT compile method
'CUSTOMER_INFO:set_Signature (Foundation.NSData)' while running with
--aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.
UPDATE after suggestion by user #SushiHangover
In my iOS binding library project in generated code I tried this workaround:
[Register("CUSTOMER_INFO", true)]
//public unsafe partial class CUSTOMER_INFO : NSObject {
public unsafe partial class CUSTOMER_INFO_GENERIC<T> : NSObject where T : NSObject
{
[CompilerGenerated]
static readonly IntPtr class_ptr = Class.GetHandle ("CUSTOMER_INFO");
public override IntPtr ClassHandle { get { return class_ptr; } }
[CompilerGenerated]
[EditorBrowsable (EditorBrowsableState.Advanced)]
[Export ("init")]
public CUSTOMER_INFO_GENERIC () : base (NSObjectFlag.Empty)
{
IsDirectBinding = GetType ().Assembly == global::ApiDefinition.Messaging.this_assembly;
if (IsDirectBinding) {
InitializeHandle (global::ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, global::ObjCRuntime.Selector.GetHandle ("init")), "init");
} else {
InitializeHandle (global::ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, global::ObjCRuntime.Selector.GetHandle ("init")), "init");
}
}
[CompilerGenerated]
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected CUSTOMER_INFO_GENERIC(NSObjectFlag t) : base (t)
{
IsDirectBinding = GetType ().Assembly == global::ApiDefinition.Messaging.this_assembly;
}
[CompilerGenerated]
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected internal CUSTOMER_INFO_GENERIC(IntPtr handle) : base (handle)
{
IsDirectBinding = GetType ().Assembly == global::ApiDefinition.Messaging.this_assembly;
}
// other methods....
// .................
[CompilerGenerated]
object __mt_Signature_var;
[CompilerGenerated]
public virtual NSData SignatureNoJit {
[Export ("signature", ArgumentSemantic.Retain)]
get {
NSData ret;
if (IsDirectBinding) {
ret = Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, Selector.GetHandle ("signature")));
} else {
ret = Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("signature")));
}
if (!IsNewRefcountEnabled ())
__mt_Signature_var = ret;
return ret;
}
[Export ("setSignature:", ArgumentSemantic.Retain)]
set {
if (value == null)
throw new ArgumentNullException ("value");
if (IsDirectBinding) {
global::ApiDefinition.Messaging.void_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle ("setSignature:"), value.Handle);
} else {
global::ApiDefinition.Messaging.void_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle ("setSignature:"), value.Handle);
}
if (!IsNewRefcountEnabled ())
__mt_Signature_var = value;
}
}
[CompilerGenerated]
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
if (Handle == IntPtr.Zero) {
__mt_Signature_var = null;
}
}
}
public class CUSTOMER_INFO_NOJIT : CUSTOMER_INFO_GENERIC<NSData>
{
// A specialized subclass and this is passed to your ObjC-based method
}
But when i call
NSData tmp = NSData.FromArray(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF });
CUSTOMER_INFO_NOJIT CustomerInfo = new CUSTOMER_INFO_NOJIT();
CustomerInfo.CardHolderEmail = CardHolderEMail;
CustomerInfo.CardHolderMobile = CardHolderMobilePhone;
CustomerInfo.SignatureNoJit = tmp;
I get this exception again:
System.ExecutionEngineException: Attempting to JIT compile method
'CUSTOMER_INFO_GENERIC`1:set_SignatureNoJit
(Foundation.NSData)' while running with --aot-only. See
http://docs.xamarin.com/ios/about/limitations for more information.
Anybody can suggest me a workaround/pattern to avoid this exception?
Thank you!
Lewix
(I might need more coffee...so take this with grain of salt... :-)
This:
public unsafe partial class CUSTOMER_INFO : NSObject {
~~~~
}
Becomes:
public unsafe partial class CUSTOMER_INFO_GENERIC<T> : NSObject where T : NSObject {
~~~~
}
class CUSTOMER_INFO : CUSTOMER_INFO_GENERIC<NSData>
{
// A specialized subclass and this is passed to your ObjC-based method
}
And thus this in your set and the get return can be resolved as NSData vs. NSObject and no jitting is required and the compiler created/resolved the classes...
I am trying to swap a nested dependency when resolving a specific instance using StructureMap. In 2.x I was able to do this with the following UseSpecial code, but it does not work in 3.x
The code is basically saying... when requesting an instance of IObject, swap the default instance for ITwo with AnotherTwo which is a dependency of IObject's dependency.
public class MyStructureMapRegistry : Registry
{
public MyStructureMapRegistry()
{
For<IObject>().UseSpecial(cfg => cfg.ConstructedBy(x =>
{
x.RegisterDefault(typeof(ITwo), x.GetInstance<AnotherTwo>());
return x.GetInstance<DependsOnOne>();
}));
}
}
The following is the sample object graph that I am trying to wire up.
public interface IObject { }
public interface IOne { }
public interface ITwo { }
public class DependsOnOne : IObject
{
IOne _one;
public DependsOnOne(IOne one)
{
_one = one;
}
}
public class DependsOnTwo : IOne
{
ITwo _two;
public DependsOnTwo(ITwo two)
{
_two = two;
}
}
public class Two : ITwo { }
public class AnotherTwo : ITwo { }
So I create and outlet by dragging the UIPicker into the .h file. I'm really new in Xamarin studio, but I have done endless amounts of research and have tried everything. Basically what I want to do is have the picker view give the user an option of numbers and when one is clicked display the amount for that option. I have tried everything I have read online but its somewhat confusing to me. As in where to put the data and what i should type in compared to what is being told.
I have a app with 2 view controllers the picker view is in the FirstViewController, I assume i put the code in there basically this is what I have but I get errors right from the start saying public PickerModelDelegate(FirstViewController) <___Parser Error: Unexpected symbol 'public' This is my demo I took out of the book just to understand what is going on :/
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace PickerViewApp
{
public class PickerModelDelegate : UIPickerViewModel
public PickerModelDelegate (FristViewController Controller)
{
thi
s.parentController = controller;
this.transportList = new List<string>()
{
"On Foot", "Bivycle", "Motocycle", "Car", "Bus"
};
this.distanceList = new List<string>()
{
"0.5", "1", "5", "10", "100"
};
this.unitList = new List<string>()
{
"mi", "km"
};
this.transportSelected = this.transportList[0];
this.distanceSelected = this.distanceList[0];
this.unitSelected = this.unitList[0];
int GetComponentCount (UIPickerView picker)
int GetRowsInComponent (UIPickerView picker, int component)
string GetTitle (UIPickerView picker, int row, int component)
void Selected(UIPickerView picker, int row, int component)
}
private FirstViewController parentController;
private List<string> transportList;
private List<string> distanceList;
private List<string> unitList;
string transportSelected;
string distanceSelected;
string unitSelected;
}
public partial class FirstViewController : UIViewController
{
public FirstViewController () : base ("FirstViewController", null)
{
Title = NSBundle.MainBundle.LocalizedString ("First", "First");
TabBarItem.Image = UIImage.FromBundle ("first");
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
}
}
}
Sorry I'm really new at this. Please dont be rude I really want to learn how to do this.
Thanks ahead for any help. I truly do appreciate it!!
You haven't implemented any of the methods that provide the picker with information on the data source.
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace PickerViewApp
{
public class PickerModelDelegate : UIPickerViewModel
{
List<string> Data;
public PickerModelDelegate (List<string> data)
{
Data = data;
this.parentController = controller;
this.transportSelected = this.transportList[0];
this.distanceSelected = this.distanceList[0];
this.unitSelected = this.unitList[0];
}
public override int GetComponentCount (UIPickerView picker)
{
// RETURN THE NUMBER OF COMPONENTS THE PICKER WILL NEED (THE NUMBER OF "SECTIONS" = THE NUMBER OF LISTS OF DATA YOU HAVE)
return 1;
}
public override int GetRowsInComponent (UIPickerView picker, int component)
{
return Data.Count;
}
public override string GetTitle (UIPickerView picker, int row, int component)
{
return Data[row];
}
}
private FirstViewController parentController;
private List<string> transportList;
private List<string> distanceList;
private List<string> unitList;
string transportSelected;
string distanceSelected;
string unitSelected;
public partial class FirstViewController : UIViewController
{
public FirstViewController () : base ("FirstViewController", null)
{
Title = NSBundle.MainBundle.LocalizedString ("First", "First");
TabBarItem.Image = UIImage.FromBundle ("first");
this.transportList = new List<string>()
{
"On Foot", "Bivycle", "Motocycle", "Car", "Bus"
};
}
public override void DidReceiveMemoryWarning ()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
this.Picker.Model = new PickerModelDelegate (transportList);
}
}
}
You can use the "component" parameter in the methods to determine which list you want to get the data for, for that specific component.
Hope that helps!
Consider I have the following types:
public interface IBaseInterface { }
public interface IInheritedInterface : IBaseInterface { }
public class MyClass : IInheritedInterface { }
//------------------------------------------------------------
public interface ISomeInterface { }
public class SomeClass : ISomeInterface {
private readonly IBaseInterface _myInterface;
public SomeClass(IBaseInterface myInterface) {
_myInterface = myInterface;
}
}
//------------------------------------------------------------
public interface ISomeOtherInterface { }
public class SomeOtherClass : ISomeOtherInterface {
private readonly IInheritedInterface _myInterface;
public SomeOtherClass(IInheritedInterface myInterface) {
_myInterface = myInterface;
}
//------------------------------------------------------------
So, what I am trying to achieve and wonder how could be done, if possible, is that whenever I construct either SomeClass or SomeOtherClass is to always get the same instance of MyClass. This example explains what I want:
var someClass = _container.Resolve<SomeClass>();
var someOtherClass = _container.Resolve<SomeOtherClass>();
// At this point, The following assert should pass
Assert.AreSame(someClass._myInterface, someOtherClass._myInterface)
Also note that MyClass needs to register using a factory method for other reasons. I have tried the following:
_container.RegisterType<IBaseInterface, MyClass>(
perRequestLifetime,
new InjectionFactory((c) =>
{ return FactoryMethod(c); }));
This will resolve SomeClass but will throw when trying to resolve SomeOtherClass since the container doesn't know how to construct IInheritedInterface.
I have also tried this:
_container.RegisterType<IBaseInterface, MyClass(
perRequestLifetime,
new InjectionFactory((c) => {
MyClass myClass;
// Construct object some how...
return myClass;
}));
_container.RegisterType<IInheritedInterface, MyClass(
perRequestLifetime,
new InjectionFactory((c) => {
return c.Resolve<IBaseInterface>() as MyClass;
}));
However, for some reason when I call Resolve() on both SomeClass and SomeOtherClass they both end up calling the factory of IInheritedInterface causing an endless loop! I then removed IBaseInterface registration and now resolving SomeClass throws.
Any ideas?
Thanks
Try this
container.RegisterType<IBaseInterface, MyClass>(new ContainerControlledLifetimeManager(), new InjectionFactory(ctr => new MyClass()));
container.RegisterType<IInheritedInterface, MyClass>();