Custom framework iOS

  1. 5 months ago
    Edited 5 months ago

    Hi,

    I hope someone can help. I am following the guide here xojo blog loading 3rd party frameworks in xojo ios to add a custom framework to my iOS project.

    I have built a framework for iOS with the following in the PenIOS.h file

    + (PenIOS *)sharedInstance;
    - (NSInteger) Test_Int;
    - (NSString *) FunctionOneString;

    And in the PenIOS.m file

    - (NSInteger) Test_Int
    {
        return 22;
    }
    
    - (NSString *) FunctionOneString
    {
        NSLog(@"Returning: Test String");
        return @"Test String";
    }
    
    + (PenIOS *)sharedInstance
    {
        static dispatch_once_t predicate = 0;
        __strong static id sharedObject = nil;
        dispatch_once(&predicate, ^{ sharedObject = [[self alloc] init]; });
        return sharedObject;
    }

    PenIOS is an NSObject with a sharedInstance as in the framework used on the blog.

    I built the framework and added it to a copy files build phase placed between the Build and Sign phases.

    I then added the following to a button but num is always 0 and Label1.Text gets set to blank when clicking the button.

    Declare Function dlopen Lib "/usr/lib/libSystem.dylib" (name As CString, flags As Int32) As Ptr
    Call dlopen("@executable_path/Penios.framework/Penios", 1 Or 8)
    
    // NOTE: We're specifically NOT using the actual lib name here. 
    // This is just to satisfy the Xojo linker. The correct framework will be used at runtime.
    Declare Function NSClassFromString Lib "Foundation" (clsName As CFStringRef) As Ptr
    Dim pbclass As Ptr = NSClassFromString("PenIOS")
    Declare Function sharedInstance Lib "Foundation" Selector "sharedInstance" (clsref As Ptr) As Ptr
    Dim pbclassShared as Ptr = sharedInstance(pbclass)
    
    Declare Function FunctionOneStr lib "Foundation" Selector "FunctionOneString" (obj as ptr) As CFStringRef
    Declare Function Test_Int lib "Foundation" Selector "Test_Int" (obj as ptr) As Integer
    
    Dim num As Integer = Test_Int(pbclassShared)
    Label1.Text = FunctionOneStr(pbclassShared)

    Any help would be appreciated.
    Thanks in advance

    First of all thank you all for your answers and taking time to reply.
    I managed to get this working finally today by just building the Framework in an older version of Xcode.

    I was building with Xcode 10.2.1 and switching to using 10.1.0 cleaning and rebuilding seems to have resolved the issue.

    Thank you again for all the help and have a great week! :D

  2. Jeremie L

    Jul 21 Pre-Release Testers, Xojo Pro, XDC Speakers Europe (France) - getpackr.io
    Edited 5 months ago

    Hi Giles,

    First make sure that the copy files build step is setup like this:

    https://ibb.co/sPgTntb

    Applies to: Both
    Subdirectory: Frameworks
    Destination: App Parent Folder

    Then I would recommend loading the framework in a function instead of doing all code in the button:

    Protected Function LoadPenIOS() as Boolean
      
      Declare Function dlopen Lib "/usr/lib/libSystem.dylib" ( path As CString, mode As Int32 ) As Ptr
      Declare Function dlerror Lib "/usr/lib/libSystem.dylib"  As CString
      
      Const RTLD_LAZY = 1
      Const RTLD_GLOBAL = 8
      
      
      Dim path As Text 
    
      
      path = "@executable_path/Frameworks/Penios"
    // or it might be
    "path = "@executable_path/Frameworks/Penios.framework/Penios"
    
      
      Dim result As ptr = dlopen(path.ToCString(xojo.core.TextEncoding.UTF8), RTLD_LAZY Or RTLD_GLOBAL )
      
      If result = Nil Then
        Dim reason As Text
        reason = Text.FromCString(dlerror, Xojo.Core.TextEncoding.UTF8)
        break //read the reason
        Return False
      End If
      
      System.DebugLog "framework opened."
      Return True
    End Function

    The rest of your code looks fine, just add:

    If LoadPenIOS then
    
    //Your code here
    
    End If
  3. Antonio R

    Jul 21 Pre-Release Testers, Xojo Pro, Third Party Store Europe (Italy)

    @Giles A Declare Function sharedInstance Lib "Foundation" Selector "sharedInstance" (clsref As Ptr) As Ptr

    I'm not sure that the "sharedInstance" you get here is what you looking for...

    you are calling the Foundation method, not your lib one...

  4. Greg O

    Jul 21 Xojo Inc scout.galaxy.barn

    @Antonio R I'm not sure that the "sharedInstance" you get here is what you looking for...

    you are calling the Foundation method, not your lib one...

    Actually he’s not. It calls the sharedInstance method of the class that’s passed.

  5. First of all thank you all for your answers and taking time to reply.
    I managed to get this working finally today by just building the Framework in an older version of Xcode.

    I was building with Xcode 10.2.1 and switching to using 10.1.0 cleaning and rebuilding seems to have resolved the issue.

    Thank you again for all the help and have a great week! :D

or Sign Up to reply!