Forum Xamarin.iOS

Deriving from a custom *base* UIViewController with a different namespace throws exception

DavidOlubajoDavidOlubajo GBMember
edited July 2015 in Xamarin.iOS

I have created a 'BaseViewController' in a Xamarin.iOS library/csproj assembly (namespace: ios_common_lib).

This 'BaseViewController' is inherited by a class named 'LoginViewController' that lives in another assembly, my main Xamarin.iOS user-facing client/csproj assembly (namespace: experiments.ios).

On the iOS emulator/iOS 8.4, everything works fine as I expect, but when I run on my iPhone 5s device/iOS 8.4, the app crashes at the point where the 'Controller' would have been rendered on the screen.

After a THOROUGH and PAINFUL investigation, I narrowed down the problem to be due to differences in the namespaces of the 'base' and 'derived' controllers. Aarggh If I make the namespaces of both my 'BaseViewController' and the derived 'Controller' to the same namespace, it works on both device and emulator.

Now, I could have just shut up, and fixed my issue by changing my namespaces, but hey, what benefit is that to anybody ? and besides i really dislike when technology tools don't work consistently, and additionally, I'd hate to change my namespaces just to fix a symptom.

So, is there anybody out there that understands what is really going on, or is this a bug? I guess it's a bug, it has to be a bug, so then should we post this on Bugzilla ?

Here is the stack trace from the exception.

**System.NullReferenceException: Object reference not set to an instance of an object
at ObjCRuntime.Runtime.FindMethod (IntPtr typeptr, IntPtr methodptr, Int32 paramCount, System.IntPtr* paramptr) [0x0005e] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/src/ObjCRuntime/Runtime.cs:566
at ObjCRuntime.Runtime.GetMethodDirect (IntPtr typeptr, IntPtr methodptr, Int32 paramCount, System.IntPtr* paramptr) [0x00000] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/src/ObjCRuntime/Runtime.cs:329
at ObjCRuntime.Runtime.get_method_direct (IntPtr typeptr, IntPtr methodptr, Int32 paramCount, System.IntPtr* paramptr) [0x00000] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/runtime/Delegates.generated.cs:178
at at (wrapper native-to-managed) ObjCRuntime.Runtime:get_method_direct (intptr,intptr,int,intptr*)
at at (wrapper managed-to-native) ObjCRuntime.Messaging:void_objc_msgSend_IntPtr (intptr,intptr,intptr)
at UIKit.UIWindow.set_RootViewController (UIKit.UIViewController value) [0x00010] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/src/build/ios/native/UIKit/UIWindow.g.cs:327
at common_lib.UIWindowExtensions.SwitchRootViewController (UIKit.UIWindow window, UIKit.UIViewController controller, Boolean animated) [0x00014] in /Users/davidolubajo/Development-Local/XamarinStudioProjects/Walkr/common_lib/Extensions/UIWindowExtensions.cs:28
at experiments.ios.AppDelegate+c__AnonStorey1+c__async0.MoveNext () [0x000c4] in /Users/davidolubajo/Development-Local/XamarinStudioProjects/Walkr/experiments.ios/AppDelegate.cs:41
at --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in /Users/builder/data/lanes/1962/8b265d64/source/mono/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:61
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.m__0 (System.Object state) [0x00000] in /Users/builder/data/lanes/1962/8b265d64/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1006
at UIKit.UIKitSynchronizationContext+c__AnonStorey0.<>m__0 () [0x00000] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/src/UIKit/UIKitSynchronizationContext.cs:24
at Foundation.NSAsyncActionDispatcher.Apply () [0x00000] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/src/Foundation/NSAction.cs:164
at at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/src/UIKit/UIApplication.cs:63
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0001c] in /Users/builder/data/lanes/1962/8b265d64/source/maccore/src/UIKit/UIApplication.cs:46
at experiments.ios.Application.Main (System.String[] args) [0x00008] in /Users/davidolubajo/Development-Local/XamarinStudioProjects/Walkr/experiments.ios/Main.cs:17
**

Best Answer

Answers

  • adamkempadamkemp USInsider, Developer Group Leader mod

    We definitely do this in our code, and it works for us. There must be something different that you're doing. Could you narrow it down to a small test case and attach a zip of that project here so I can look at it?

  • DavidOlubajoDavidOlubajo GBMember

    Hi @adamkemp ,

    Big fan of your blog here.. :blush: i've learned so much on iOS and android from just a few of your blog posts. I can't wait for your next post on 'taming the android activity'. Thanks for all your effort and contribution.

    So, enough of that and back to business...

    I've actually narrowed down the issue to the right problem. It was because in my 'AppDelegate' 'DidFinishedLaunching', I was instantiating my window to a variable local to that method; not to the virtual 'Window' property that the AppDelegate naturally provides. See below...

        public override UIWindow Window { get; set; }
    
        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            // I was doing this...
            var Window = new UIWindow(UIScreen.MainScreen.Bounds);
    
            //instead of this
            Window = new UIWindow(UIScreen.MainScreen.Bounds);
    
            Window.RootViewController = new ClientController();
    
            Window.MakeKeyAndVisible();
    
            return true;
        }
    

    Very very subtle, for the mere fact that it worked on the emulator, but not on the device.

    TBH, i've had a number of scenarios that work on the emulator but not on the device.

    It would be really nice if the two environments worked consistently....

Sign In or Register to comment.