yahoo / squidb

SquiDB is a SQLite database library for Android and iOS
https://github.com/yahoo/squidb/wiki
Apache License 2.0
1.31k stars 132 forks source link

squidb-ios: why not a pod ? or another type of dependency? #199

Open aminelaadhari opened 8 years ago

aminelaadhari commented 8 years ago

One of the recommended ways to do cross platform using j2objc is to have a shared library that you translate using with j2objc. There is some tools like j2objc-gradle (https://github.com/j2objc-contrib/j2objc-gradle) which makes the process straightforward.

For example here is my project structure:

Adding the dependency for an ios app isn't as straightforward as the android app. You have to deal with mixed rules and environments. It would be lot easier to make a pod or another type of dependency that you use directly in swift of objc.

sbosley commented 8 years ago

The main reason is that the SquiDB devs are all Java people who don't have any experience with cocoapods, and we haven't recruited an iOS dev to figure out the best way to set that up yet. We've just been using Xcode build rules. Contributions are welcome though!

aminelaadhari commented 8 years ago

I see. I am a beginner in the ios world but it feels like the wrong way and a real obstacle to the adoption of squidb by the ios people. I will explore a few things with more experienced ios devs and try to make a contribution.

sbosley commented 8 years ago

According to the j2objc-gradle doc:

You should start with a clean Java only project without any Android dependencies. It is suggested that the project is named shared. It must be buildable using the standard Gradle Java plugin.

j2objc actually does support a limited set of Android dependencies (see here), which we've been using in our shared code and building using the "android" gradle plugin. I don't know if this is a hard and fast restriction in j2objc-gradle, but it's just something to be aware of, as it sounds like j2objc-gradle may not be suitable for all project setups. Any changes we make to squidb should probably be agnostic to whether or not the user wants to use the j2objc-gradle plugin.

sbosley commented 8 years ago

To make sure I understand the situation fully -- in your project, it sounds like the j2objc-gradle plugin works ok for adding your shared code and core squidb dependency to the iOS project -- so is squidb-ios the only pain point because of the mix of Java and native code?

aminelaadhari commented 8 years ago

yes exactly

aminelaadhari commented 8 years ago

For example, this library https://github.com/vals-productions/sqlighter provides the ios part in a fully native way

aminelaadhari commented 8 years ago

Finally I wrote two gradle tasks to get squidb-ios source code, include the files in the translate task of j2objc-gradle + copy its native code to the objc output folder. I had to change the includes of the native code to match the output of j2objc-gradle.

I can share the gradle tasks here if interested.

jdkoren commented 8 years ago

@aminelaadhari Awesome, we'd be very happy if you shared it for the benefit of others who might be in the same situation as you.

aminelaadhari commented 8 years ago

For java files, I created a fake configuration called ios which allows me to get java files from it. I include theses files into the translation task using the option generatedSourceDirs. For native code, I didn't find an easy solution so I copied the files to a folder ios-native. j2objc-gradle don't use the options --no-package-directories to avoid file collision, so I had to change the import pahts in SQLiteErrors.m to follow the generated files structure. I copy these files to the build/j2objcSrcGenMain/ at the end of the translation task of j2objc-gradle.

SQLiteErrors.m modified imports:

import "com/yahoo/android/sqlite/SQLiteException.h"

import "com/yahoo/android/sqlite/SQLiteDiskIOException.h"

import "com/yahoo/android/sqlite/SQLiteDatabaseCorruptException.h"

import "com/yahoo/android/sqlite/SQLiteConstraintException.h"

import "com/yahoo/android/sqlite/SQLiteAbortException.h"

import "com/yahoo/android/sqlite/SQLiteDoneException.h"

import "com/yahoo/android/sqlite/SQLiteFullException.h"

import "com/yahoo/android/sqlite/SQLiteMisuseException.h"

import "com/yahoo/android/sqlite/SQLiteAccessPermException.h"

import "com/yahoo/android/sqlite/SQLiteDatabaseLockedException.h"

import "com/yahoo/android/sqlite/SQLiteTableLockedException.h"

import "com/yahoo/android/sqlite/SQLiteReadOnlyDatabaseException.h"

import "com/yahoo/android/sqlite/SQLiteCantOpenDatabaseException.h"

import "com/yahoo/android/sqlite/SQLiteBlobTooBigException.h"

import "com/yahoo/android/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.h"

import "com/yahoo/android/sqlite/SQLiteOutOfMemoryException.h"

import "com/yahoo/android/sqlite/SQLiteDatatypeMismatchException.h"

import "com/yahoo/android/sqlite/OperationCanceledException.h"

and the gradle file:

configurations {
    ios
}

dependencies {
    ...
    ios 'com.github.yahoo.squidb:squidb-ios:3.0.0:sources'
}

task copyIosSourceFiles(type: Copy) {
    from { 
        configurations.ios.collect { zipTree(it) }
    }
    into 'build/j2objc/source/dependencies/'
}

task copyIosNativeFiles(type: Copy) {
    from '../ios-native/'
    into 'build/j2objcSrcGenMain/'
}

gradle.projectsEvaluated {
    j2objcTranslate.dependsOn copyIosSourceFiles
    j2objcTranslate.finalizedBy copyIosNativeFiles
}

j2objcConfig {
    ...
    generatedSourceDirs 'build/generated/source/apt/main'
    generatedSourceDirs 'build/j2objc/source/dependencies/'

    extraLinkerArgs '-lsqlite3'
    ...
}