Using an Objective C framework, which is inside a Swift framework, in a Xamarin iOS project

Hello iPhone application developers 🙂 The blog post I’m going to write today is more over sharing my personal experience rather than teaching you a lesson. If we take whole scenario, I believe this is a very rare case that a single developer will encounter. But there are lots of things that you can learn from this post. Final goal of this post is, implement a Xamarin iOS application, which uses a third party Swift framework that uses another third party Objective C framework.

For the understanding perspective, we will categorize this post in to three subtopics.

Create an Objective C framework

As for the start, create a Cocoa Touch Framework project.

AnujAroshA_iOS_ObjectiveC_1

Selecting a Cocoa Touch Framework

Next fill details in the next window. Make sure to select Objective C as the Language.

AnujAroshA_iOS_ObjectiveC_2

Fill project related details

Once you created the project, your Project Navigator will be looks like below.

AnujAroshA_iOS_ObjectiveC_3

Expanded Project Navigator

As you can see, a default header file has been created for you. That file act more like a bridge to access the functions inside this framework. In other words, the headers you need to be public should mention here. You can see the modified header later.

AnujAroshA_iOS_ObjectiveC_4

Bridging header file

Now you can add your code in new files by adding Cocoa Touch Classes.

AnujAroshA_iOS_ObjectiveC_5

Adding Cocoa Touch Classes

If you plan to access methods in this class, make sure subclass it with NSObject. Also, keep remember that our ultimate goal is to use this framework inside a Xamarin iOS project.

AnujAroshA_iOS_ObjectiveC_6

Name your class

As for the demonstration purpose, I’m using only a single function in that file. One thing you have to remember is make your class public under Target Membership category. By default it set as project.

AnujAroshA_iOS_ObjectiveC_7

Make the header file public

Like I mentioned earlier, you have to add this header file to your bridging file as well. So the modified bridging file will be look like below.

AnujAroshA_iOS_ObjectiveC_8

Modified bridging file

Now you need to concern about some settings. I set the Deployment Target as 10. One reason for that is, I needed this framework should compatible with armv7 architecture as well. If you need to have an idea about the iOS versions and supporting architectures, this will be a good link.

AnujAroshA_iOS_ObjectiveC_10

Selecting a deployment target

Next, adding the architectures that you need.

AnujAroshA_iOS_ObjectiveC_9

Adding architectures

Next setting is, disable Bitcode for the target. The reason for this is to compatible with Xamarin apps, because Xamarin does not include Bitcode and Apple needs all the libraries have the same architecture.

AnujAroshA_iOS_ObjectiveC_11

Disable Bitcode

Now, edit the scheme as below by setting the Build Configuration as Release and remove the tick mark from the Shared option.

AnujAroshA_iOS_ObjectiveC_12

Edit Scheme

Now we need to create an Aggregate target and add a Run Script to make things easy. I have explained how to do it in one of my previous post. So I am not going to repeat the steps and the content of the Run Script here. But make sure to update following settings to Aggregate target as well.

  • Same Valid Architectures
  • Disable Bitcode
  • Edit Scheme

Since I have shown you those steps clearly with screenshots above, I’m not going to explain it again.

Final step is build the framework target by selecting Generic iOS Device option and the build the Universal target. Now your Objective C framework is ready. This part of the code is hosted in a GitLab repository.

Creating a Swift framework using the Objective C framework

Now we are going to include previously created Objective C framework inside a newly building Swift framework. I’ll use bullet points since most of the steps are same as creating Objective C framework.

  • Create a Cocoa Touch Framework project
  • Drag and drop the previously created Objective C project in to your Project Navigator
AnujAroshA_iOS_Swift_7_1

Drag and drop Objective C framework

  • Set Deployment Target to 10
  • Add Valid Architectures same as in the above framework
  • Disable Bitcode
  • Edit Scheme as previously

Using an Objective C framework inside a Swift framework is little bit different. To do that we need to create a custom Swift module. This is how you are going to do that.

  • Start to create an Aggregate target
  • As for the Product Name of the Aggregate target, give the Objective C framework name
AnujAroshA_iOS_Swift_10

Give Objective C framework name as the Product Name

  • Add a Run Script to create the modulemap. Script will be similar to below. Make sure to replace it with your Objective C framework name
if [ -d "${BUILT_PRODUCTS_DIR}/AnujaObjectiveCFramework" ]; then
echo "${BUILT_PRODUCTS_DIR}/AnujaObjectiveCFramework directory already exists."
exit 0
fi

mkdir -p "${BUILT_PRODUCTS_DIR}/AnujaObjectiveCFramework"
cat <<EOF > "${BUILT_PRODUCTS_DIR}/AnujaObjectiveCFramework/module.modulemap"
module AnujObjcModule {
header "${PROJECT_DIR}/AnujaObjectiveCFramework.framework/Headers/AnujaObjectiveCFramework.h"
export *
}
EOF
  • Update following settings for this Aggregate target as well
    • Valid Architectures
    • Disable Bitcode
    • Edit Scheme
  • Build that Aggregate target by selecting Generic iOS Device
  • Now, add that built aggregate target under Target Dependencies of your Swift framework target.
AnujAroshA_iOS_Swift_16

Add modulemap target as a Target Dependency

  • Now you can add the Swift class that uses Objective C library
import UIKit
import AnujaObjectiveCFramework

@objc (AroshaMathPerformer)
open class AroshaMathPerformer: NSObject {

    @objc open func doTheMath() -> String {

        let result = AnujaMathPerformer().addTwoNumbers(3, 4)
        return "Result is \(result)"
    }
}
  • As the next step, you can create the Universal target with the Run Script
  • Final step is, build the modulemap target, then framework target and lastly the universal target

That will conclude the implementation of the Swift framework which included the Objective C framework. You can access the source in a Git repository here.

Using the Swift framework in a Xamarin iOS application

Final phase of the post is using above created frameworks inside a Xamarin iOS application. Here I have not much to say because I have written a separate post on this topic earlier. But I need to highlight two major points.

  1. Make sure to sign your build by adding a valid Team with a valid Developer Provisioning Profile.
  2. If you have built the framework with Swift 5 and running the application in same version, you do not need to add all the Swift related NuGet packages but Xamarin.Swift will be enough.

You can access this part of the source from this GitLab repository. Last but not least, I would like to thank Lucas Teixeira, for the conversations we had over the Twitter related to issues that I faced. Let’s meet from a different challenge in another day 🙂

About AnujAroshA

Working as an Associate Technical Lead. Specialized in iOS application development. A simple person :)
This entry was posted in iOS, Swift, Xamarin and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s