Bug 55522 - Unable to instantiate Storyboard shipped inside iOS Binding Library
Summary: Unable to instantiate Storyboard shipped inside iOS Binding Library
Status: RESOLVED ANSWERED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: unspecified
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Future Cycle (TBD)
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-04-24 15:09 UTC by patryk.romanczuk
Modified: 2017-10-09 15:22 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Solution where storyboard failes to compile into Binding Library (332.25 KB, application/zip)
2017-04-27 10:38 UTC, patryk.romanczuk
Details
Files required to detect bug. Contains mentioned obj-c app with framework usage. (208.31 KB, application/zip)
2017-06-06 13:05 UTC, patryk.romanczuk
Details
InvalidTyping (320.65 KB, image/png)
2017-06-22 15:02 UTC, patryk.romanczuk
Details
Invalid Cast Exception (286.17 KB, image/png)
2017-06-23 06:32 UTC, patryk.romanczuk
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description patryk.romanczuk 2017-04-24 15:09:56 UTC
Hello,

I would like to report in Xamarin.iOS. My project requires to use iOS Binding Library with native Framework included. This Framework written in Swift provides few Storyboard files that i need to reference but... I'm unable to instantiate them.

Calling UIStoryboard.FromName with null Bundle causes quite obvious exception "FromFramework" Storyboard not found. Because this method calls for app bundle and framework has different.

var storyboard = UIStoryboard.FromName("FromFramework", null);

But when i try to call this method with specifing bundles weird things happens. 

new NSBundle("com.company.framework")
var bundleId = NSBundle.FromIdentifier("com.company.framework");
var bundle = NSBundle.FromClass(new ObjCRuntime.Class(typeof(FromFrameworkViewController)));

None of this method allows me to retrieve my framework bundle returning either null or exception

I tried also doing another way around :
Copied storyboard files from framework source to result app.
Tried to instantiate storyboard + viewcontroller manually.

var storyboard = UIStoryboard.FromName("FromFramework", null);
var vc = storyboard.InstantiateViewController("FromFrameworkViewController");
var actual = vc as FromFrameworkViewController;

Unfortunately created viewController isn't of type FromFrameworkViewController (Invalid Cast Exception). Storyboard contains only one viewcontroller scene.

I asked questions on both xamarin forums and stackoverflow. I tried anything that i was able to find and still I'm unable to instantiate storyboard object which leads me to thinking it's some kind of a bug.
Comment 1 Alex Soto [MSFT] 2017-04-25 14:56:51 UTC
Hello Thanks for contacting us, this is a dupe of bug #12851.

That being said a workaroud for this is that you manually compile storyboards to storyboarc and add them to Resources folder in the binding project. using ibtool you can compile them.

> ibtool --output-format human-readable-text --compile MyStoryboard.storyboardc MyStoryboard.storyboard

*** This bug has been marked as a duplicate of bug 12851 ***
Comment 2 Alex Soto [MSFT] 2017-04-26 15:58:16 UTC
Hello Patryk

(In reply to patryk.romanczuk from comment #7)
> I sucessfully managed to load storyboard in my app from binding library by
> referencing manually compiled storyboard resource file but it goes with
> another problem.
> 
> Storyboard comes from a Swift Framework (I am aware that it is not
> officially supported, but it is possible by working with Framework-Swift.h)
> and referencing such framework in Binding Library results in creating
> SwiftName attributes in ApiDefinition like this : 
> 
> Name = "_TtC15NPUIPlayerTheme24FrameworkViewController"
> 
> Obviusly from my code i see this classes as normally named
> FrameworkViewController, but... when i try to instantiate ViewController
> from referenced in this way framework it ends with:
> 
> Unknown class _TtC15NPUIPlayerTheme24FrameworkViewController in Interface
> Builder file.
> 
> Is there any possible way to workaround this issue? It is crucial for me to
> use this framework.

This goes a little out of the Bugzilla's support scope but please can you provide us a test project including your swift binding so I can reproduce the issue you are getting and see if I can give you a solution? I have marked this bug as private so you can attach it here
Comment 3 patryk.romanczuk 2017-04-27 10:38:16 UTC
Created attachment 21847 [details]
Solution where storyboard failes to compile into Binding Library

Solutions contains iOS Single Page project which references Binding Library Project. Also I included xcode framework source from which i created Framework, compiled fat library framework and compiled storyboard
Comment 4 patryk.romanczuk 2017-04-27 10:45:54 UTC
I really appreciate time you give to look at this bug. It took me a while because i wanted to be 100% sure so I created entire solution and framework for you that contains this bug that i am talking. 

Brief description of steps made to create solution in attachment:

1. Created working swift framework containing storyboard and viewcontroller class
2. Created binding library for swift using this recipe:
http://stackoverflow.com/documentation/xamarin.ios/6091/binding-swift-libraries#t=201704270814169620846
3. Compiled manually storyboard file and added reference to it in Resources folder in Binding Library
4. Successfully created storyboard UIStoryboard.FromName
5. Instantiated InitialViewController but failed to cast it into specific type with error:  Unknown class _TtC13TestFramework27FromFrameworkViewController in Interface Builder file.

There is also one thing that concerns me :

Framework has it's own bundle identifier but :

var bundle2 = NSBundle.FromClass(new ObjCRuntime.Class(typeof(FromFrameworkViewController)));

this call where i pass a framework binded class a parameter results in MainBundle object.

var bundleId = NSBundle.FromIdentifier("com.test.TestFramework");

This call on the other hand, results in null but i think it should return Framework Bundle
Comment 5 patryk.romanczuk 2017-05-10 07:28:19 UTC
Hello,

May I ask if there is any chance of fixing or finding a workoaround for these bugs? After trying it for few times I still believe there are actually 3 problems here.

1. Storyboard/Xib not compiling into binding library
(solved by manually compiling but involves another bug)
2. Manually compiled storyboards misses viewcontrollers from binding library
3. Wrong bundle id for binding swift frameworks

I understand that this problems may be uncommon and there is no official support for swift frameworks but this problems deadlock my projects.

Thanks for help.
Comment 6 Alex Soto [MSFT] 2017-05-10 13:53:11 UTC
Hello Patryk

I am very sorry I missed your last reply in this bug, I will have a look at this tomorrow's morning, I need one last thing to be able to figure out a solution, an ObjC app consuming this framework you created I can surely create it but if you can help me with this today I can just start on the actual problem tomorrow.

Thanks in advance and again sorry for missing your last reply.
Comment 7 patryk.romanczuk 2017-05-11 14:25:35 UTC
Hello Alex,

I'm sorry that i didn't send you ObjC project. I didn't had time to create it. Are you able to go without it or create it on your own? If yes i would be really gratefull if not - please give me day or two I'll find time to create it for you

Thanks, Patryk Romańczuk
Comment 8 patryk.romanczuk 2017-06-06 13:05:10 UTC
Created attachment 22718 [details]
Files required to detect bug. Contains mentioned obj-c app with framework usage.

Hello,

Finally I'm able to bring you required obj-c app that shows this bug. In obj-c code it works just as it should do (matching bundle, resolved view controller for storyboard) and still in xamarin.ios this issue happens.

Thank you in advance, Patryk Romańczuk
Comment 9 patryk.romanczuk 2017-06-06 13:06:24 UTC
After additional testing, and creating obj-c app this issue still bothers me. I would really appreciate if you would find some time to look upon this problem.
Comment 10 patryk.romanczuk 2017-06-21 10:52:22 UTC
Hello,

I'd like to ask if there is there any chance that this bug will be fixed or will be provided any workaround? It blocks in our company few projects simultanously. 

I would be extremally gratefull for any hint about it. It works as expected in Obj-C (we provided mentioned app) and does not work in Xamarin.

Thank you in advance, Patryk Romańczuk
Comment 11 Alex Soto [MSFT] 2017-06-21 15:16:20 UTC
Hello, unfortunately, swift is not yet officially supported so what we can do is try to give suggestions to workaround limitations. Also thanks for providing a sample.

I am surprised that your swift framework comes with a storyboard instead of a storyboardc. If you look closer to the TestFramework.framework files you provided, it contains a storyboardc. What we need to do is to find the right ibtool command options to get that storyboard turned into a storyboardc that the swift runtime can work with.

It seems xcode is doing this in two steps, this creates the storyboardc

> xcrun ibtool --errors --warnings --notices --module TestFramework --auto-activate-custom-fonts --target-device iphone --target-device ipad --minimum-deployment-target 10.3 --output-format human-readable-text TestStoryboard.storyboard

And then it links it with the TestFramework.framework

> xcrun ibtool --errors --warnings --notices --module TestFramework --target-device iphone --target-device ipad --minimum-deployment-target 10.3 --output-format human-readable-text --link TestFramework.framework TestStoryboard.storyboardc

Replace TestFramework/TestFramework.framework with your actual framework and TestStoryboard.storyboard with your storyboard and add it to your binding project as you did in comment #2.

If the above does not work, I will need you to send us the framework files you are actually working on with the binding project and a small demo to repro this particular issue. Unfortunately, the project you created seems not to be 100% the same as your original issue in the sense that TestFramework.framework already contains a storyboardc not a storyboard.

Please let me know if it works and sorry for the late response I know I offered to help even if this is not supported just could not allocate the time to craft something for you.
Comment 12 patryk.romanczuk 2017-06-22 15:02:58 UTC
Created attachment 23059 [details]
InvalidTyping
Comment 13 patryk.romanczuk 2017-06-22 15:10:09 UTC
Hello,

I made a screenshot that quite well describes what's bothering our project.

Our framework is shipped with a storyboardc inside. It's probably my spelling that you thought that we have .storyboard inside. But thats not a case. 

What i did right now:
1. Using provided sample i changed one thing - Inside Frameworks Storyboard I added Storyboard Id to View Controller object inside Storyboard file.
2. In sample App i managed to:
  a)  Create storyboard using UIStoryboard.FromName
  b)  Instatiated View Controller using story.InstatiateViewController("FromFrameworkViewController")
  c)  I checked created object and it is absolutely valid viewController. I can clearly see my subviews using local inspector (look at attached screenshot. You can clearly see them in Subviews of variable "vc1".
  d) I try to cast "vc1" which internally is my FromFrameworkViewController to actual type and it results in null reference. Force casting crashes the app.

Just one thing holds us from successfull workaround - this cast that happens between "vc1" and "newVc1" which i shown at screenshot.

Thank you for all your help
Comment 14 Alex Soto [MSFT] 2017-06-22 18:03:57 UTC
I see what you mean, do you mind trying the following, add the following helper to your code

https://gist.github.com/dalexsoto/d04ff3a1c226757667b776d64d308b1b

This should allow you to do 

> var story = UIStoryboard.FromName ("FromFramework", null);
> var vc1 = story.InstantiateViewController<FromFrameworkViewController> ("FromFrameworkViewController");

So vc1 should have the right subclass.

Please let me know if this works for you
Comment 15 patryk.romanczuk 2017-06-23 06:32:01 UTC
Created attachment 23067 [details]
Invalid Cast Exception

Hello,

Unfortunately using Storyboard helper didn't helped us. It still has problems with casting. This time, throwing System.InvalidCastException
Comment 16 patryk.romanczuk 2017-06-23 06:32:50 UTC
Also - maybe this will help i attach exception and stacktrace:

Exception
System.InvalidCastException: Specified cast is not valid. at at (wrapper castclass) System.Object:__castclass_with_cache (object,intptr,intptr) at ObjCRuntime.Runtime.ConstructNSObject[T] (System.IntPtr ptr, System.Type type, ObjCRuntime.Runtime+MissingCtorResolution missingCtorResolution) [0x0003e] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/ObjCRuntime/Runtime.cs:951 at ObjCRuntime.Runtime.GetNSObject[T] (System.IntPtr ptr) [0x000e4] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/ObjCRuntime/Runtime.cs:1078 at TestFrameworkUsage.StoryboardHelper.InstantiateViewController[T] (UIKit.UIStoryboard story, System.String identifier) [0x00008] in /Users/patrykromanczuk/Documents/BugSolution/BuggyFramework/TestFrameworkUsage/ViewController.cs:41 at TestFrameworkUsage.ViewController.ViewDidLoad () [0x00027] in /Users/patrykromanczuk/Documents/BugSolution/BuggyFramework/TestFrameworkUsage/ViewController.cs:29 at at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/UIKit/UIApplication.cs:79 at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/UIKit/UIApplication.cs:63 at TestFrameworkUsage.Application.Main (System.String[] args) [0x00001] in /Users/patrykromanczuk/Documents/BugSolution/BuggyFramework/TestFrameworkUsage/Main.cs:12

StackTrace
  at (wrapper castclass) System.Object:__castclass_with_cache (object,intptr,intptr)
  at ObjCRuntime.Runtime.ConstructNSObject[T] (System.IntPtr ptr, System.Type type, ObjCRuntime.Runtime+MissingCtorResolution missingCtorResolution) [0x0003e] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/ObjCRuntime/Runtime.cs:951 
  at ObjCRuntime.Runtime.GetNSObject[T] (System.IntPtr ptr) [0x000e4] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/ObjCRuntime/Runtime.cs:1078 
  at TestFrameworkUsage.StoryboardHelper.InstantiateViewController[T] (UIKit.UIStoryboard story, System.String identifier) [0x00008] in /Users/patrykromanczuk/Documents/BugSolution/BuggyFramework/TestFrameworkUsage/ViewController.cs:41 
  at TestFrameworkUsage.ViewController.ViewDidLoad () [0x00027] in /Users/patrykromanczuk/Documents/BugSolution/BuggyFramework/TestFrameworkUsage/ViewController.cs:29 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/UIKit/UIApplication.cs:79 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/4691/d2270eec/source/xamarin-macios/src/UIKit/UIApplication.cs:63 
  at TestFrameworkUsage.Application.Main (System.String[] args) [0x00001] in /Users/patrykromanczuk/Documents/BugSolution/BuggyFramework/TestFrameworkUsage/Main.cs:12
Comment 17 patryk.romanczuk 2017-06-23 11:42:18 UTC
After tons of options tried I have finally found a solution.

https://github.com/Flash3001/Xamarin.Swift3.Support

Adding last update of Swift3.Support packages allows us to create and cast object of interesting us type.

Anyway - I really appreciate all the effort you gave us in helping our issue. Thank you very much!
Comment 18 Alex Soto [MSFT] 2017-06-23 14:29:00 UTC
mmm I wonder if I can give you a better solution than adding that big nuget package

If your development happens on a mac try adding the following to the bottom of your app's csproj

https://gist.github.com/dalexsoto/e1878713a15b4091215dc50d720afa49

This should bring only the needed swift libraries needed by your app. If you development happens on windows then just keep using that nuget.

Let me know if you tried the above :) I'm happy you figured this out.
Comment 19 patryk.romanczuk 2017-06-26 08:06:42 UTC
Wow!

You're a genius. This swift framework copying magic spell works like a charm. 

Thanks you very much!

Also: All attachments that we provided here can be shown as public, so you can disable "Private Bug" if anyone would have same issue - they can find solution here.
Comment 20 Alex Soto [MSFT] 2017-06-26 14:44:34 UTC
Glad it worked, removed the private flag. Thanks for your patience and letting me know it worked!