Is it allowed in iOS - Swift Dynamic Framework - Contains Multiple Static Library


I have developed a framework for my customer, thats a swift dyanmic framework. For code modularization i have divided this framework features in to multiple static libraries as shown in the diagram below. Currently we have on main swift dynamnic framework and it contains 2 static libraries too. Also the first static library here in turn nested with another static library, Key points to note here is

My static libraries contains other third party iOS frameworks My static libraries using CoccoaPods as the dependency for Alarmofire at the moment.

My questios are

Is there any problem in the current architecture , because i heard nested libraries are not supported in iOS . but since we dont have frameworks nested here, all of our second level frameworks are static libraries only. What are link/libary search path guidance we needed to take care to make a successful build.

I don't know whether I'm completely correct, but I've always checked for type metadata accessors for types in the statically linked libraries. If I have more than one type metadata accessor for given type, might have a problem.


Consider following files:

// % cat stat.swift
public struct MyFoo { public init() {} }

// % cat dyn.swift
import stat
public func dyna1foo() -> stat.MyFoo { .init() }

// % cat dyn2.swift
import stat
public func dyna1foo() -> stat.MyFoo { .init() }

// % cat main.swift 
import dyn
import dyn2

let a = dyn.dyna1foo()
let b = dyn2.dyna1foo()

print(type(of: a) == type(of: b))

Built using:

% swiftc -parse-as-library -emit-library -emit-module -static stat.swift
% swiftc -parse-as-library -emit-library -emit-module -I. -L. -lstat -Xlinker -rpath -Xlinker . dyn.swift
% swiftc -parse-as-library -emit-library -emit-module -I. -L. -lstat -Xlinker -rpath -Xlinker . dyn2.swift 
% swiftc -I. -L. -ldyn -ldyn2 -Xlinker -rpath -Xlinker . main.swift   

Then if I run main in LLDB and do this:

(lldb) b main
(lldb) r
(lldb) image lookup -rn MyFoo #I assume all dynamic libraries are loaded at this time

and lldb goes something like this:

3 matches found in libdyn.dylib:
        Address: libdyn.dylib[0x0000000000003f18] (libdyn.dylib.__TEXT.__text + 0)
        Summary: libdyn.dylib`dyn.dyna1foo() -> stat.MyFoo        Address: libdyn.dylib[0x0000000000003f2c] (libdyn.dylib.__TEXT.__text + 20)
        Summary: libdyn.dylib`stat.MyFoo.init() -> stat.MyFoo        Address: libdyn.dylib[0x0000000000003f30] (libdyn.dylib.__TEXT.__text + 24)
        Summary: libdyn.dylib`type metadata accessor for stat.MyFoo
3 matches found in libdyn2.dylib:
        Address: libdyn2.dylib[0x0000000000003f18] (libdyn2.dylib.__TEXT.__text + 0)
        Summary: libdyn2.dylib`dyn2.dyna1foo() -> stat.MyFoo        Address: libdyn2.dylib[0x0000000000003f2c] (libdyn2.dylib.__TEXT.__text + 20)
        Summary: libdyn2.dylib`stat.MyFoo.init() -> stat.MyFoo        Address: libdyn2.dylib[0x0000000000003f30] (libdyn2.dylib.__TEXT.__text + 24)
        Summary: libdyn2.dylib`type metadata accessor for stat.MyFoo

I have a problem, because there are two type metadata accessor for stat.MyFoo.

I might not be correct, tho. I would appreciate if anybody would correct me if I'm mistaken.

And sometimes you can get warning, for example if you change MyFoo from struct to class you can get this warning: objc[93532]: Class _TtC4stat5MyFoo is implemented in both /path/libdyn2.dylib (0x1048180d0) and /path/libdyn.dylib (0x1048080d0). One of the two will be used. Which one is undefined.


1 Like