Linking to a Swift Framework in Xamarin07 Feb 2018
I recently had to add a Swift framework into a Xamarin iOS app, and it was really complicated.
There are multiple web pages that try to explain how to do this, but none of them matched my eventual solution. Therefore I thought it would be useful to share what I did, in case it’s of some use to someone wrestling with the same problem.
A client I’m working with wanted to integrate the Visa Checkout SDK into their Xamarin iOS app.
Visa have pretty good documentation on how to do this for a native iOS app, but the latest version of their SDK is written in Swift.
Now Xamarin has a tool called Objective Sharpie which lets you import an Objective-C library, but it doesn’t natively support Swift frameworks.
However with quite a bit of effort you CAN get this to work. This is what I did …
N.B. For other frameworks and/or setups these exact steps may not work for you! Take what you can from these instructions and good luck (you’ll need it!)
Instructions for binding the VisaCheckoutSDK framework
- Install Objective Sharpie - instructions here
- Setup a new binding project in Visual Studio for Mac, using Add -> Add new Project … -> iOS -> Library -> Bindings Library on your existing solution
- Download the VisaCheckoutSDK via Cocoapods:
- Make a new directory
- Run the command
sharpie pod init ios VisaCheckoutSDK.
- This uses Objective Sharpie to setup a pod directory to download the latest SDK code.
- Hack the info.plist file in the downloaded pod to make it look like it was built by the version of XCode Objective Sharpie uses:
sharpie xcode -sdksand note the SDK used for iPhone builds e.g. “iphoneos11.2”
- In the info.plist file in the downloaded VisaCheckoutSDK pod, change the DTSDKName to the value from above e.g. “iphoneos11.2”
- You can now generate the C# binding files used in the binding project you setup earlier by running
sharpie pod bind
- Overwrite the ApiDefinition.cs and StructsAndEnums.cs files in the binding project with the files generated in the previous step
The generated files won’t build out of the box, so need editing to get them to work. This is what I did to make them usable:
- Changed enums in StructsAndEnums.cs to be long
- Added Namespace of VisaCheckoutSDK.Touch to generated files
- Fixed up warnings by commenting out duplicate implementations in generated code i.e. those that have the same parameters etc.
- Removed empty generated interfaces
- Commented out “using VisaCheckoutSDK” in ApiDefinition.cs - not 100% sure why this was necessary!
Hopefully you can then build the linking project, and hence use it in your Xamarin iOS app.
One thing to note is I had to add multiple Xamarin.Swift3.* packages in the main app to allow the Swift VisaCheckoutSDK to run. Without the correct Swift packages, the app failed to load after the splash screen on startup.
It was very difficult to consistent get the error message for the missing Swift packages, as the app often crashed before the debugger could attach and get the error message in the logs. I ended up adding all the Swift packages I could find, and then removing them one by one until the app crashed again. Clearly not a great way to do this :(
This was insanely hard, and took me a good couple of days to figure out all these steps.
Having to do this is definitely a big downside of using Xamarin versus native iOS solutions, and has definitely made me think again about when to use Xamarin for cross-platform projects.