iOS Declare with local framework

This is the first time I’m writing my own declares on iOS.
If the framework is not in the system (like all the examples I can find out there) how to I reference the path?

I think the lib will need to use the special “@executable_path” string in order to specify the location. I haven’t used it on iOS, but that’s what you do on MacOS.

Ah, I should have known that.
Thanks, Jason.

Make sure the lib is copied to the Frameworks folder using a copy files build step.

You can then reference it like this:

Soft Declare Function myFunctionName Lib "@executable_path/Frameworks/LibName" () As Integer
1 Like

That’s what I was looking for. Thanks.
Now the issue is, as I dig in, I will not be able to access this framework via declares because it is setup with classes not just function calls.
Frustrated.

to access the classes inside you’ll probably need to load the framework. Here’s a method that’ll help you with that:

Public Sub LoadFramework(FrameworkNameOrPath as String)
  Declare Function dlopen Lib "/usr/lib/libSystem.dylib" (name As CString, flags As Int32) As Ptr
  
  Dim flags As Integer = 8
  
  // If the user just passed the name of a framework to load, look in the system frameworks directory
  If FrameworkNameOrPath.IndexOf("/") = -1 Then
    FrameworkNameOrPath = FrameworkNameOrPath.Replace(".framework", "")
    FrameworkNameOrPath = "/System/Library/Frameworks/" + FrameworkNameOrPath + ".framework/" + FrameworkNameOrPath
    flags = 5
  End If
  
  // Only load the framework if it hasn't been before
  Static LoadedLibraries() As String
  If LoadedLibraries.IndexOf(FrameworkNameOrPath) = -1 Then
    Call dlopen(FrameworkNameOrPath, flags)
    LoadedLibraries.Append FrameworkNameOrPath
  End If
  
End Sub
1 Like

In case the framework does not load, which happened to me a couple times, this code can help:

Public Sub LoadFramework(FrameworkNameOrPath as String)
  Declare Function dlopen Lib "/usr/lib/libSystem.dylib" (name As CString, flags As Int32) As Ptr
  
  Dim flags As Integer = 8
  
  // If the user just passed the name of a framework to load, look in the system frameworks directory
  If FrameworkNameOrPath.IndexOf("/") = -1 Then
    FrameworkNameOrPath = FrameworkNameOrPath.Replace(".framework", "")
    FrameworkNameOrPath = "/System/Library/Frameworks/" + FrameworkNameOrPath + ".framework/" + FrameworkNameOrPath
    flags = 5
  End If
  
  // Only load the framework if it hasn't been before
  Static LoadedLibraries() As String
  If LoadedLibraries.IndexOf(FrameworkNameOrPath) = -1 Then
    Dim result as Ptr = dlopen(FrameworkNameOrPath, flags)
    If result = Nil Then
  		Dim reason As String
  		Declare Function dlerror Lib "/usr/lib/libSystem.dylib" As CString
  		reason = dlerror
  		break
  	Else
    	LoadedLibraries.Append FrameworkNameOrPath
    End if
  End If
  
End Sub

Wouldn’t you usually use CFBundle or NSBundle APIs from Apple for that instead of lower level dlopen()?

All,

I’m confused. I always believed that if the framework had classes that I’d have to make a plugin.
Am I wrong?

Depends on the library.
If anything touches threads or is time critical, a plugin may be required.

See also More than just a wrapper

Yeah, I fully expect this needs a plugin.

Not necessarily. Declares can create instances of classes using NSClassFromString, alloc and init.