Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding a .dylib inside a framework for iOS

I've been trying to submit a Swift app with an Obj-C Dynamic Library (.dylib) which keeps getting rejected by the iOS App Store with error messages such as

Invalid Swift Support - The files libswiftDarwin.dylib, libswiftDispatch.dylib, libswiftCoreGraphics.dylib, libswiftUIKit.dylib, libswiftCore.dylib, libswiftFoundation.dylib, libswiftQuartzCore.dylib, libswiftObjectiveC.dylib, libswiftCoreImage.dylib aren’t at the expected location /Payload//Frameworks. Move the file to the expected location, rebuild your app using the current public (GM) version of Xcode, and resubmit it

From the Apple docs at https://developer.apple.com/library/archive/technotes/tn2435/_index.html#//apple_ref/doc/uid/DTS40017543-CH1-PROJ_CONFIG-APPS_WITH_DEPENDENCIES_BETWEEN_FRAMEWORKS the error "may indicate your app is embedding a dynamic library that is not packaged as a framework. Dynamic libraries outside of a framework bundle, which typically have the file extension .dylib, are not supported on iOS, watchOS, or tvOS, except for the system Swift libraries provided by Xcode."

So the next step was to embed the Dynamic Library (as a subproject) within a Cocoa Touch Framework project. Once that was set up, although the framework built fine, I got stuck on "symbol not found" errors for the imported dylib classes.

I would like to know the steps required to achieve this project structure, or if its even possible on iOS.

like image 386
Adamski Avatar asked Dec 17 '18 15:12

Adamski


1 Answers

I was able to submit an app with a .dylib by creating a framework first. I first tried the method described in the apple documentation, but got errors when submitting to the store ( "invalid bundle. the bundle at xyz.framework contains disallowed file 'Frameworks' )

What i did was use lipo to manually package my .dylib into a framework.

$ lipo -create mylib.dylib -output mylib

Now you get a binary file called 'mylib' Create a folder called mylib.framework and put the binary file in it. Then add an Info.plist ( you can just copy and modify one from an existing framework. ) In the Info.plist, fill out the fields for your framework. The main one to update or add is "Executable" which should be the name of that binary file.

I had another issue where another framework I was using was referencing my original .dylib, which is gone and now inside the framework. To fix this I used the "install_name_tool" to modify the other framework to look for my new framework.

$ cd OtherLib.framework 
$ install_name_tool -change @rpath/mylib.dylib @rpath/mylib.framework/mylib OtherLib

You can read more about that tool in this good blog post: https://medium.com/@donblas/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172

like image 155
Morty Avatar answered Oct 07 '22 07:10

Morty