Shared Project: Android app and iOS app sample apps

Seems they start at 1, so it really should be Bind…(i+1, …)

Note that I already fixed this for ios/osx a while ago:

(develop branch)

Let’s look at my code a second:

           private func testSelect(conn:SQLiteConnection!) -> Bool {
		do {
				
			let SELECT = "SELECT * from CACHE"
			let result:SQLiteQueryResult= try executeQuery(conn, query:SELECT , parameters:[]);
			
			while result.MoveNext() {
				logger.debug( result.GetString( 0 ) ); // col1
				logger.debug( result.GetString( 1 ) ); // col2
				logger.debug( result.GetString( 2 ) ); // col3
			}
			
		} catch let error as SQLiteException {
			logger.error("sql error",error:error);
			return false;
		}
		return true;
	} //testSelect

I should have then all columns, but now I have just realized that

On iOS I get

1
USER_765609548
PIPPO
2
USER_-1994321905
PIPPO

and the missing a parameter as well :confused: if we consider that the insert was

                let INSERT = "INSERT OR REPLACE INTO CACHE (cache_key, cache_value, timestamp) VALUES (?,?,?);";
		try executeInsert(conn, query:INSERT , parameters:[key,"PIPPO","20150101"]);

@ck Attaching here database example db.sql.zip (1.2 KB)

The data structure is like

So doing the while

                     while result.MoveNext() {
				var i=0;
				logger.debug( result.GetString( i++ ) ); // col1
				logger.debug( result.GetString( i++ ) ); // col2
				logger.debug( result.GetString( i++ ) ); // col3
			}

I was supposed to move from index 0 (the first column CACHE_KEY to last column TIMESTAMP, but of course I was wrong since it starts from the auto increment so the right code was:

                    let SELECT = "SELECT * from CACHE"
			let result:SQLiteQueryResult= try executeQuery(conn, query:SELECT , parameters:[]);
			while result.MoveNext() {
				var i=0;
				logger.debug( Convert.toString( result.GetInt( i++ ) ) ); // col1 autoinc
				logger.debug( result.GetString( i++ ) ); // col2
				logger.debug( result.GetString( i++ ) ); // col3
				logger.debug( result.GetString( i++ ) ); // col4
			}


1
USER_765609548
PIPPO
20150101
2
USER_-1994321905
PIPPO
20150101
3
USER_-105582610
PIPPO
20150101

so the db structure and query parameters binding in SQLiteHelpers.BindArgs for iOS target it’s ok, but on Android it goes beyond the index and in that case and I get a weird

java.lang.RuntimeException: Unable to start activity ComponentInfo{musixmatch.com.sampleandroidapp/musixmatch.com.sampleandroidapp.MainActivity}: java.lang.IllegalArgumentException: message

Last, but not least, if I look at the logs on Android:

01-25 18:17:37.564 14739-14739/? I/System.out: 5
01-25 18:17:37.564 14739-14739/? I/System.out: PIPPO
01-25 18:17:37.564 14739-14739/? I/System.out: 20150101
01-25 18:17:37.584 14739-14739/? I/System.out: 6
01-25 18:17:37.584 14739-14739/? I/System.out: PIPPO
01-25 18:17:37.584 14739-14739/? I/System.out: 20150101

it seems that the columns are in fact moved +1 and therefore at every run I overwrite the same two cols:

01-25 18:32:30.358 15206-15206/? I/System.out: 6
01-25 18:32:30.358 15206-15206/? I/System.out: PIPPO
01-25 18:32:30.358 15206-15206/? I/System.out: 20150101
01-25 18:32:30.441 15206-15206/? I/System.out: 7
01-25 18:32:30.441 15206-15206/? I/System.out: PIPPO
01-25 18:32:30.441 15206-15206/? I/System.out: 20150101

@ck I have found the solution!
You were partially right, in fact in Sugar.Data SQLite.pas you missed to move ahead the column i+1 in the SQLiteHelpers.BindArgs

{$IFDEF ANDROID}
method SQLiteHelpers.ArgsToString(arr: array of Object): array of String;
begin
  if length(arr) = 0 then exit [];
  result := new String[arr.length];
  for i: Integer := 0 to arr.length -1 do begin
    result[i] := arr[i]:toString(); 
  end;
end;

method SQLiteHelpers.BindArgs(st: android.database.sqlite.SQLiteStatement; aArgs: array of Object);
begin
  for i: Integer := 0 to length(aArgs) -1 do begin
    var val := aArgs[i];
    if val = nil then
      st.bindNull(i + 1)
    else if val is Double then
      st.bindDouble(i + 1, Double(val))
    else if val is Single then
      st.bindDouble(i + 1, Single(val))
    else if val is Int64 then
      st.bindLong(i + 1, Int64(val))
    else if val is Int64 then
      st.bindLong(i + 1, Int64(val))
    else if val is array of SByte then 
      st.bindBlob(i + 1, array of SByte(val))
    else 
      st.bindString(i + 1, val.toString);
  end;
end;
{$ENDIF}

Now everything works properly (and of course the array index in the loop is ok as it was:
for i: Integer := 0 to length(aArgs) -1 do begin

So, I’m going to mark this as a solution when a bug has been filed.
Thank you.

1 Like

Can you submit a pull request for the fix?

ok I will do. Thank you.

1 Like

@mh Hello, I have updated in my examples projects two Fire Swift apps for iOS (SampleAppiOS/) and Android (SampleAndroidAppFire/)
See: https://github.com/loretoparisi/swift-promise-example

Both compiles and run without any external (projects) dependency on a iPhone6 / Nexus7 I’m targeting.

When adding the SharedProject to the **SampleAppiOS** I get an error:

: CrossBox error Link: ld: library not found for -lSugar

I have added as references both Sugar.fx and Sugar.Data.fx. Those were recompiled from the develop branch of Sugar to have the latests fixes. And I have those libraries in the folder:

StaticLibrary/mylibs/

The detailed log of ld is

Executing /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld -arch armv7 -ObjC "/Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/SampleiOSApp/obj/Debug/iOS/armv7/SampleiOSApp.o"  -lSystem -lobjc  -framework CoreGraphics -framework Foundation -framework UIKit -l"Nougat" -l"Swift" -l"Sugar" -l"sqlite3" -l"Sugar.Data" -l"xml2" -L"/Applications/Fire.app/Contents/Resources/Reference Paths with Data Abstract Trial/Nougat/../../References/Elements/Nougat/iOS" -dynamic -o "./obj/Debug/iOS/armv7/SampleiOSApp"  -syslibroot "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk" -demangle -ios_version_min               9.2 -rpath @executable_path -dead_strip -force_load "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/7.0.2/lib/darwin/libclang_rt.ios.a" 
ld: ld: library not found for -lSugar
:  CrossBox error Link: ld: library not found for -lSugar


                       Compiling for architecture arm64
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CoreGraphics.fx
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/Foundation.fx
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/UIKit.fx
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/rtl.fx
                            Reference: /Applications/Fire.app/Contents/Resources/Reference Paths with Data Abstract Trial/Nougat/../../References/Elements/Nougat/iOS/libNougat.fx
                            Reference: /Applications/Fire.app/Contents/Resources/Reference Paths with Data Abstract Trial/Nougat/../../References/Elements/Nougat/iOS/libSwift.fx
                            Reference: /Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/StaticLibrary/mylibs/libSugar.fx
                            Reference: /Applications/Fire.app/Contents/Resources/Reference Paths with Data Abstract Trial/Nougat/../../References/CoreReferences/Nougat/iOS/libsqlite3.fx
                            Reference: /Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/StaticLibrary/mylibs/libSugar.Data.fx
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CoreFoundation.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/Security.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CFNetwork.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CoreText.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/QuartzCore.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/Metal.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/OpenGLES.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CoreImage.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CoreVideo.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CoreData.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Nougat SDKs/iOS 9.2/CoreLocation.fx (implicit)
                            Reference: /Applications/Fire.app/Contents/Resources/Reference Paths with Data Abstract Trial/Nougat/../../References/CoreReferences/Nougat/iOS/libxml2.fx (implicit)

and the BUILD FAILED.

On the Android project, SampleAndroidAppFire when adding the SharedProject
I have the another issue. Here I’m using the latest builded sugar.jar, sugar.data.jar from the develop of Sugar as well, and the libraries are in the folder:

StaticLibrary/ClassLibrary2/mylibs/

The error this time is just a case sense error (like the other we had before on SQLite.pas :slightly_smiling: and it is

StaticLibrary/SharedProject/src/API/APIClient.swift(66,23): error E511: No member “ToString” on type “sugar.json.JsonObject!”, did you mean “toString”?

referred to APIClient class where I was doing:

let myObject:Sugar.Json.JsonObject = Sugar.Json.JsonObject.Load( jsonObject.ToString() );

Note: When compiling the Android Static Library + SharedProject that is in StaticLibrary/ClassLibrary2 that are sharing the same sugar.jar and sugar.data.jar
I get not warn/errors about this case sensitive issue.

Thank you for your help!

So, regarding the Android app project SampleAndroidAppFire, if I enable in Settings Cross-Platform Compatibility Mode the case sensitive error goes way. In fact it makes sense due to the case insensitive nature of Cocoa. Problem two solved.

1 Like

Curious. Is -L"/Applications/Fire.app/Contents/Resources/Reference Paths with Data Abstract Trial/Nougat/…/…/References/Elements/Nougat/iOS" correct and does it contain libSugar.a?

Uhm not sure, in turn it changes the error for both the two user libs:

CrossBox error Link: ld: library not found for -lSugar.Data

but the library is there:

Reference: /Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/StaticLibrary/mylibs/libSugar.Data.fx

While libSugar.fx is threated as having this reference path:

                            Reference: /Applications/Fire.app/Contents/Resources/Reference Paths with Data Abstract Trial/Nougat/../../References/CoreReferences/Nougat/iOS/libSugar.fx

even if they are in the same folder and I have added them in the same way: Add Reference > Browse > Add.

@mh I’m sorry, I have missed something in the Elements compiler architecture! I needed both the .fx and .a files in mylibs/ folders when compiling in Elements (this was not needed in Xcode).
So, iOS Fire app SampleiOSApp issue fixed!.

1 Like

Yes, the linker needs the .a, witch is the actual binary. the compiler needs the .fx, which is our metadata.

Amazing, the last (but not least) issue is in the Android sample app. Dalvik ClassLoader complains that does not find the Lsugar/Environment so Sugar.Environment.

Stacktrace:

02-04 14:49:39.577 17962-17962/? D/AndroidRuntime: Shutting down VM
02-04 14:49:39.578 17962-17962/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: org.me.sampleandroidappfire, PID: 17962
                                                   java.lang.NoClassDefFoundError: Failed resolution of: Lsugar/Environment;
                                                       at org.me.sampleandroidappfire.SharedClassTest.context(/Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/StaticLibrary/SharedProject/src/Library.swift:86)
                                                       at org.me.sampleandroidappfire.MainActivity.onCreate(/Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/SampleAndroidAppFire/MainActivity.swift:27)
                                                       at android.app.Activity.performCreate(Activity.java:6251)
                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                       at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:148)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                    Caused by: java.lang.ClassNotFoundException: Didn't find class "sugar.Environment" on path: DexPathList[[zip file "/data/app/org.me.sampleandroidappfire-1/base.apk"],nativeLibraryDirectories=[/data/app/org.me.sampleandroidappfire-1/lib/arm, /vendor/lib, /system/lib]]
                                                       at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                       at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                                                       at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                                                       at org.me.sampleandroidappfire.SharedClassTest.context(/Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/StaticLibrary/SharedProject/src/Library.swift:86) 
                                                       at org.me.sampleandroidappfire.MainActivity.onCreate(/Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/SampleAndroidAppFire/MainActivity.swift:27) 
                                                       at android.app.Activity.performCreate(Activity.java:6251) 
                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                       at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:148) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                                                   	Suppressed: java.lang.ClassNotFoundException: sugar.Environment
                                                       at java.lang.Class.classForName(Native Method)
                                                       at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
                                                       at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
                                                       at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                                                       		... 15 more
                                                    Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

while AndroidStudio (plus additional jar rtl dependencies) it compile and runs.
I have the jars in mylibs/, I have unchecked in Fire Local Copy from the References:

macbookproloreto:tests admin$ ls -l /Volumes/MacHDD2/Developmemt/ParisiLabs/swift-promise-example/StaticLibrary/ClassLibrary2/mylibs 
-rw-r--r--  1 admin  staff    4670 27 Gen 16:43 sugar.data.jar
-rw-r--r--  1 admin  staff  155833  4 Feb 14:53 sugar.jar

Now If I look at the jar class files. I can see the Environment.class within…
Thank you for your support!

Further debugging info about this issue in Fire:

The error is still:

java.lang.NoClassDefFoundError: Failed resolution of: Lsugar/Environment;

and I confirm that running the same code (hopefully same base jars) I have no error in AndroidStudio.

Thanks, logged as bugs://74492

Just to be clear: Copy Local is set to true for Sugar right?

It was set to false. I cleaned the project, set to true, but I see the same issue.

ah ke. Does sound like a bug. I’m going to look at this monday hopefully.

1 Like

So I’ve been trying this:

An exception of type: java.lang.RuntimeException occurred
Message: {java.lang.RuntimeException: Unable to start activity ComponentInfo{org.me.sampleandroidappfire/org.me.sampleandroidappfire.MainActivity}: java.lang.SecurityException: caller uid 10047 lacks any of android.permission.GET_ACCOUNTS}

Changed it by adding:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

then it works (latest compiler)

1 Like

bugs://74492 got closed with status fixed.