iOS Question Help with Objective C Library

walterf25

Expert
Licensed User
Longtime User
Hi All, i decided to give it a shot and try to wrap a small library, so far everything is going good, i am able to add the customview with the designer, also I can see the event been raised when the view is dragged.

The problem i'm having is with some of the methods being used, i get the following error when I try to set the left value and the right value.

iRangeBar1.setMinMaxValue(30, 120)
no visible @interface for 'iRangeBar' declares the selector 'setMinMaxValuemaxValue::'

To be more specific the library is a RangeBarSlider, so you can set the Minimum Value and the Maximum Value, also you can set the starting value of the left and right knobs.

In my .h file i have the following properties defined:
header file:
@interface iRangeBar : B4IViewWrapper <B4IDesignerCustomView>
- (void)DesignerCreateView:(B4IPanelWrapper *)base :(B4ILabelWrapper *)lw :(B4IMap *)props;
- (void)setMinMaxValue:(double)minValue maxValue:(double)maxValue;
- (void)setLeftValue:(double)leftValue rightValue:(double)rightValue;
- (void)setMinimumDistance:(double)minimumDistance;

And in the iRangebar.m file i have the following:
iRangeBar.m:
- (void)setMinMaxValue:(double)minValue maxValue:(double)maxValue{
    [OBJ setMinValue:minValue maxValue:maxValue];
}

- (void)setLeftValue:(double)leftValue rightValue:(double)rightValue{
    [OBJ setLeftValue:leftValue rightValue:rightValue];
}

- (void)setMinimumDistance:(double)minimumDistance{
    [OBJ setMinimumDistance:minimumDistance];
}

And here's the code in B4i
iRangeBar library:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Private pg As Page
    Private iRangeBar1 As iRangeBar
End Sub

Public Sub Show
    If pg.IsInitialized = False Then
        pg.Initialize("pg")
        pg.RootPanel.LoadLayout("settings")
        pg.Title = ""
    End If
    Log("minval: " & iRangeBar1.minimumValue)
    iRangeBar1.setMinimumDistance(50)
    iRangeBar1.setMinMaxValue(30, 120)
   iRangeBar1.setLeftValue(50, 90)
    Main.NavControl.ShowPage(pg)

End Sub

Sub iRangeBar1_SliderValueChanged (leftValue As Double, rightValue As Double)
    LogColor("leftval: " & leftValue & " -- " & "rightVal: " & rightValue, Colors.Blue)
End Sub

If I comment out iRangeBar1.setMinMaxValue and iRangeBar1.setLeftValue lines then everything works, the iRangeBar1.setMinimumDistance works perfect, which is what I don't understand, why would that line work but not the setminmaxvalue and the setleftvalue.

Does anyone have any input on this?

Thanks,
Walter
 
Last edited:

JordiCP

Well-Known Member
Licensed User
Longtime User
Parameter labels (what you have at the left of the ":" when the method has more that one param) are optional but not compulsory in Objective-C.
They give problems when they appear in the interface that will be wrapped with B4I

A way to get rid of this error is not to use labels, so your declarations would be this way:

(untested)

header file:
B4X:
@interface iRangeBar : B4IViewWrapper <B4IDesignerCustomView>
- (void)DesignerCreateView:(B4IPanelWrapper *)base :(B4ILabelWrapper *)lw :(B4IMap *)props;
- (void)setMinMaxValue:(double)minValue :(double)maxValue;    // <-- Here, we have removed the 'maxValue' label for the 2nd param
- (void)setLeftValue:(double)leftValue :(double)rightValue;           // <-- Same as above. Here, we have removed the 'rightValue' label for the 2nd param
- (void)setMinimumDistance:(double)minimumDistance;

iRangeBar.m:
B4X:
- (void)setMinMaxValue:(double)minValue :(double)maxValue{   // <-- Here, we have removed the 'maxValue' label for the 2nd param
[OBJ setMinValue:minValue maxValue:maxValue]; // <-- No need to strip it here if it is an internal method that is not exposed to B4I
}

- (void)setLeftValue:(double)leftValue :(double)rightValue{ // <-- Same as above. Here, we have removed the 'rightValue' label for the 2nd param
[OBJ setLeftValue:leftValue rightValue:rightValue]; //<-- Same as above. No need to strip here if it is an internal method not exposed to B4I
}

- (void)setMinimumDistance:(double)minimumDistance{ //<-- No changes here
[OBJ setMinimumDistance:minimumDistance];
}

It doesn't happen with 'setMinimumDistance' method because it only has one parameter, so there is no 'label' :)
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Parameter labels (what you have at the left of the ":" when the method has more that one param) are optional but not compulsory in Objective-C.
They give problems when they appear in the interface that will be wrapped with B4I

A way to get rid of this error is not to use labels, so your declarations would be this way:

(untested)

header file:
B4X:
@interface iRangeBar : B4IViewWrapper <B4IDesignerCustomView>
- (void)DesignerCreateView:(B4IPanelWrapper *)base :(B4ILabelWrapper *)lw :(B4IMap *)props;
- (void)setMinMaxValue:(double)minValue :(double)maxValue;    // <-- Here, we have removed the 'maxValue' label for the 2nd param
- (void)setLeftValue:(double)leftValue :(double)rightValue;           // <-- Same as above. Here, we have removed the 'rightValue' label for the 2nd param
- (void)setMinimumDistance:(double)minimumDistance;

iRangeBar.m:
B4X:
- (void)setMinMaxValue:(double)minValue :(double)maxValue{   // <-- Here, we have removed the 'maxValue' label for the 2nd param
[OBJ setMinValue:minValue maxValue:maxValue]; // <-- No need to strip it here if it is an internal method that is not exposed to B4I
}

- (void)setLeftValue:(double)leftValue :(double)rightValue{ // <-- Same as above. Here, we have removed the 'rightValue' label for the 2nd param
[OBJ setLeftValue:leftValue rightValue:rightValue]; //<-- Same as above. No need to strip here if it is an internal method not exposed to B4I
}

- (void)setMinimumDistance:(double)minimumDistance{ //<-- No changes here
[OBJ setMinimumDistance:minimumDistance];
}

It doesn't happen with 'setMinimumDistance' method because it only has one parameter, so there is no 'label' :)
Makes a lot of sense, will try to it later on today and will report back.

Thanks,
Walter
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Parameter labels (what you have at the left of the ":" when the method has more that one param) are optional but not compulsory in Objective-C.
They give problems when they appear in the interface that will be wrapped with B4I

A way to get rid of this error is not to use labels, so your declarations would be this way:

(untested)

header file:
B4X:
@interface iRangeBar : B4IViewWrapper <B4IDesignerCustomView>
- (void)DesignerCreateView:(B4IPanelWrapper *)base :(B4ILabelWrapper *)lw :(B4IMap *)props;
- (void)setMinMaxValue:(double)minValue :(double)maxValue;    // <-- Here, we have removed the 'maxValue' label for the 2nd param
- (void)setLeftValue:(double)leftValue :(double)rightValue;           // <-- Same as above. Here, we have removed the 'rightValue' label for the 2nd param
- (void)setMinimumDistance:(double)minimumDistance;

iRangeBar.m:
B4X:
- (void)setMinMaxValue:(double)minValue :(double)maxValue{   // <-- Here, we have removed the 'maxValue' label for the 2nd param
[OBJ setMinValue:minValue maxValue:maxValue]; // <-- No need to strip it here if it is an internal method that is not exposed to B4I
}

- (void)setLeftValue:(double)leftValue :(double)rightValue{ // <-- Same as above. Here, we have removed the 'rightValue' label for the 2nd param
[OBJ setLeftValue:leftValue rightValue:rightValue]; //<-- Same as above. No need to strip here if it is an internal method not exposed to B4I
}

- (void)setMinimumDistance:(double)minimumDistance{ //<-- No changes here
[OBJ setMinimumDistance:minimumDistance];
}

It doesn't happen with 'setMinimumDistance' method because it only has one parameter, so there is no 'label' :)
That worked great @JordiCP , thank you so much for that tip, however when i try to compile the app in release mode i get the following error, i'm not sure what i'm missing, i placed the generated iRangeBar.a file in the Lib folder of my Local Mac B4iBuildserver along with the iRangeBar.h file, so not sure what i may be missing now.

ld: warning: ignoring file ../../Libs/libiRangeBar.a, building for iOS-armv7 but attempting to link with file built for iOS-arm64
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_iRangeBar", referenced from:
objc-class-ref in b4i_settingspage.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Any ideas?

Thanks,
Walter
 
Upvote 0

JordiCP

Well-Known Member
Licensed User
Longtime User
Are you building your B4I project for 64bits? (Make sure that in your B4I IDE Tools>Build Server>Server settings, the 64-bit is selected)
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Are you building your B4I project for 64bits? (Make sure that in your B4I IDE Tools>Build Server>Server settings, the 64-bit is selected)
Yes, I checked and it is set for 64 bits.

Walter
 
Upvote 0

JordiCP

Well-Known Member
Licensed User
Longtime User
Then, I would check the following in your XCode project:
  • Check that you the project is build for "Generic iOS device" and not a specific one (Top XCode Bar)
  • Also, I would check these settings :
    • Select Target>Build Settings>Architectures, and there, Select "STANDARD ARCHITECTURES" if this is not the current setting).
    • Also, in this same Group, there is an entry: 'Build Active Architecture Only'. Should be set to 'NO'
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Then, I would check the following in your XCode project:
  • Check that you the project is build for "Generic iOS device" and not a specific one (Top XCode Bar)
  • Also, I would check these settings :
    • Select Target>Build Settings>Architectures, and there, Select "STANDARD ARCHITECTURES" if this is not the current setting).
    • Also, in this same Group, there is an entry: 'Build Active Architecture Only'. Should be set to 'NO'
I just tried everything you suggested but i keep getting the same error, not sure what's gong on.

I'ts interesting because it compiles in debug mode.

Walter
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Then, I would check the following in your XCode project:
  • Check that you the project is build for "Generic iOS device" and not a specific one (Top XCode Bar)
  • Also, I would check these settings :
    • Select Target>Build Settings>Architectures, and there, Select "STANDARD ARCHITECTURES" if this is not the current setting).
    • Also, in this same Group, there is an entry: 'Build Active Architecture Only'. Should be set to 'NO'
I had the minVersion set to 8, i changed to 11 and it compiles fine now, i guess the library files don't support any lower versions.

Anyway, all good now, thanks for your help.

Walter
 
Upvote 0

JordiCP

Well-Known Member
Licensed User
Longtime User
I had the minVersion set to 8, i changed to 11 and it compiles fine now, i guess the library files don't support any lower versions.
Great!
For whatever reason, seems that the lib is built only for 64 bits, and, by changing minVersion in the IDE to 11, only the 64-bit version of the B4I app is built for release (since iOS 11 dropped support for 32-bit apps), so everything matches, but who knows 🙂
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Great!
For whatever reason, seems that the lib is built only for 64 bits, and, by changing minVersion in the IDE to 11, only the 64-bit version of the B4I app is built for release (since iOS 11 dropped support for 32-bit apps), so everything matches, but who knows 🙂
That makes sense, this is my first try at wrapping a B4i library, i'm sure there are lots of things to learn, but it would be interesting to read @Erel 's input on this, i would like for this library to support lower versions as well, before posting the library to the forum.

Walter
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
iOS 11+ is popular enough now that you can ignore 32 bit devices: https://david-smith.org/iosversionstats/
If you do want to support the other 1% devices then you need to build a fat library. It is done with a tool named lipo merges binaries. It is best to compile with x86_64, armv7 and arm64.
Note that a 64 bit only library will not work with the simulator.

You can also use lipo -i to check the binaries included in an 'a' file.
 
Upvote 0
Top