All Projects → SwiftJava → Swiftjava

SwiftJava / Swiftjava

Licence: other
Swift to Java Bridge

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Swiftjava

AndroidDemo
Android 例程
Stars: ✭ 19 (-94.31%)
Mutual labels:  android-development
Slidingrootnav
DrawerLayout-like ViewGroup, where a "drawer" is hidden under the content view, which can be shifted to make the drawer visible.
Stars: ✭ 2,939 (+779.94%)
Mutual labels:  android-development
Country Picker Android
A simple library that displays a beautiful list of all the countries allowing the user to pick the country he wishes and provide details like country code, iso code name,currency and flag.
Stars: ✭ 317 (-5.09%)
Mutual labels:  android-development
Best-Coding-practices-in-android
This repo is to add best practices that developers can apply to write clean, short and testable code in android.
Stars: ✭ 86 (-74.25%)
Mutual labels:  android-development
Android Camera Example
A sample android camera example
Stars: ✭ 261 (-21.86%)
Mutual labels:  android-development
Editdrawabletext
EditDrawableText - An EditText which makes your Drawable Clickable
Stars: ✭ 288 (-13.77%)
Mutual labels:  android-development
workmanager
Scheduling background tasks without worrying about device compatibility using android WorkManager
Stars: ✭ 19 (-94.31%)
Mutual labels:  android-development
Expenso
📊 A Minimal Expense Tracker App built to demonstrate the use of modern android architecture component with MVVM Architecture
Stars: ✭ 325 (-2.69%)
Mutual labels:  android-development
Android Pagination With Recyclerview
Pagination (Endless or Infinite Scrolling) using RecyclerView's onScrollListener
Stars: ✭ 269 (-19.46%)
Mutual labels:  android-development
Lingver
Manage your application locale and language.
Stars: ✭ 300 (-10.18%)
Mutual labels:  android-development
MessageView
MessageView helps you to create chat message view or a social media message view quickly like a typical chatting application or social post view Its a container view, so you can add any type of message or social post such as TextView or any customize TextView, ImageView, etc.
Stars: ✭ 21 (-93.71%)
Mutual labels:  android-development
Tableview
TableView is a powerful Android library for displaying complex data structures and rendering tabular data composed of rows, columns and cells.
Stars: ✭ 2,928 (+776.65%)
Mutual labels:  android-development
The Pit Of The Android Studio
👍 👍 👏 🌟 ⭐️ ⭐️ Everything about the Android Studio and Intellij IDEAfor example:Install,common problems and solutions,each libraries for android and androidx library,code and peoject templates,etc.全面总结Android Studio以及Intellij IDEA的填坑指南,详解AS版本号、Gradle版本、BuildTools三者的对照关系,AS模板配置,gradle插件,Android自带注解库详解,support详解等干货。
Stars: ✭ 296 (-11.38%)
Mutual labels:  android-development
bigbang-template
Android template used by Xmartlabs team
Stars: ✭ 14 (-95.81%)
Mutual labels:  android-development
Curvegraphview
A highly customizable and performant custom view to render curved line graph.
Stars: ✭ 321 (-3.89%)
Mutual labels:  android-development
rules4android
A collection of JUnit 4 Rules for Android Developers 🔬
Stars: ✭ 23 (-93.11%)
Mutual labels:  android-development
Mixanimationsmotionlayout
En este repo encontraras multiples ejemplos de animaciones con #MotionLayout
Stars: ✭ 271 (-18.86%)
Mutual labels:  android-development
Fastadapter
The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction...
Stars: ✭ 3,512 (+951.5%)
Mutual labels:  android-development
Lost
A drop-in replacement for Google Play services location APIs for Android
Stars: ✭ 327 (-2.1%)
Mutual labels:  android-development
Android Cleanarchitecture Kotlin
This is a movies sample app in Kotlin, which is part of a serie of blog posts I have written about architecting android application using different approaches.
Stars: ✭ 3,646 (+991.62%)
Mutual labels:  android-development

SwiftJava - bridging Swift to a JavaVM

I know you've been thinking.. "What I really need is a way to bridge Swift to Java" but there are a number of use cases:

  1. Making Java technologies such as JDBC available to macOS applications.

  2. Giving Swift applications on Linux a portable user interface using Swing.

  3. Making business logic in written in Swift available to Android apps.

SwiftJava is a Swift code generator along with a small framework of supporting code written in the Xcode beta6 vintage of Swift 3.0. The starting point was Boris Bügling's Cross Platform Swift talk. The code generator takes a java class, interface or package and generates Swift classes that interface to corresponding Java methods using the Java Native Interface "JNI". These generated methods on the corresponding Swift class look something like this:

    /// public java.lang.String java.lang.Object.toString()

    private static var toString_MethodID_7: jmethodID?

    open func toString() -> String! {
        var __args = [jvalue]( repeating: jvalue(), count: 1 )
        let __return = JNIMethod.CallObjectMethod( object: javaObject, methodName: "toString", methodSig: "()Ljava/lang/String;", methodCache: &JavaObject.toString_MethodID_7, args: &__args, locals: nil )
        return JNIType.decode( type: String(), from: __return )
    }

On macOS, this has been used to generate frameworks bridging the java.lang, java.util, java.sql, java.awt and javax.swing packages along with the Apple specific additions in the com.apple package. This makes the Java apis available with auto-completion in the Xcode source editor. The final application can be a ".app" or a command line utility which should be portable to Linux using the Swift Package manager. For Android, the code generator can generate JNI code for a pair of interfaces from Java to Swift and from Swift to Java saving the developer the chore of a lot of error prone manual stubbing.

To use, clone this project using the following command:

    git clone https://github.com/SwiftJava/SwiftJava.git --recurse-submodules

This project contains the pre-generated java frameworks, an example macOS app using JDBC and a command line project with assorted AWT and Swing source. Development inside Xcode uses the legacy "JavaVM" framework which requires Apple's JVM downloadable from:

https://support.apple.com/kb/dl1572?locale=en_US

Development inside Xcode with the Oracle JVM is a little more complicated. It seems that JNI_CreateJavaVM generates a SIGSEGV internally as part of normal operation which is trapped using a signal handler so it can proceed on the command line. Unfortunately, this is caught by Xcode debugger lldb and it suspends and will not continue until you enter pr h -s false SIGSEGV into the debug console each time you run the program. The alternative is to not use the debugger at all in your scheme.

Perversely, with AWT and Swing on macOS the JVM needs to be created on the main thread while setup code needs to be off the main thread to leave it available for AWT's own runloop. Use the JNI.background and JNI.run methods to achieve this in a portable manner.

When using the Swift package manager to build code from the command line, install the latest Oracle JDK and locate the directory containing the file libjvm.so or .dylib in the jre. Use the examples. directory to build using the following commands:

    git clone https://github.com/SwiftJava/examples.git
    cd examples

    export JVM_LIBRARY_PATH=$JAVA_HOME/jre/lib/server # macOS
    export JVM_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/server # Linux

    ulimit -n 10000 # increase file descriptors for link

    swift build -Xlinker -L$JVM_LIBRARY_PATH -Xlinker -rpath -Xlinker $JVM_LIBRARY_PATH -Xlinker -ljvm

The swing source in "examples/Sources" shows how to receive events and subclass a Java class to have certain methods such as java.awt.Canvas.paint() be implemented in Swift. More on this later.

Android Development

For Android, consult the modified versions of the swift-android-samples and the associated gradle build system plugin from the Android Toochain. This run on macOS or Ubuntu 16.04, and requires a Lollipop (api 21) or better device. More detaills and context are available in the Swift README for Android and this comprehensive tutorial but hopefully the scripts in the modified gradle plugin take most of the pain out of it.

Once you have a toolchain and run its setup.sh script you should be able to type the following commands:

    cd swift-android-samples/swifthello
    ./gradlew installDebug

For a new application, define two Java interfaces, one for messaging from Java to Swift with it's name ending in "Listener" and one for messaging back into Java from Swift. You then use ./genswift.sh from this project to generate the Swift binding code:

    ./genswift.sh your.package your.jar

This generates Swift classes and a third Java source src/org/swiftjava/your_package/YourAppProxy.java that also needs to be included in your project. Consult the script genhello.sh and project "swift-android-samples/swifthello" for details. The source "swift-android-samples/swifthello/src/main/swift/Sources/main.swift" shows how to set this up with a native method called from the main activity.

    import java_swift

    var responder: SwiftHelloResponderForward!

    class ListenerImpl: SwiftHelloListenerBase {

        override func processNumber( number: Double ) {
            responder.processedNumber( number+42.0 )
        }

        override func processText( text: String? ) {
            var out = String()
            for _ in 0..<100 {
                out += "Hello "+text!+"! "
            }
            responder.processedText( out )
        }

    }	

    @_silgen_name("Java_net_zhuoweizhang_swifthello_SwiftHello_bind")
    public func bind( __env: UnsafeMutablePointer<JNIEnv?>, __this: jobject?, __self: jobject? )-> jobject? {
        responder = SwiftHelloResponderForward( javaObject: __self )
        return ListenerImpl().javaObject
    }

Forward, Runnable, Listener, Adapter, subclass responsibility and Base classes.

For every Java interface the code generator generates a Swift Protocol along with a ProtocolForward class an instance of which conforms to the protocol and can be used to message Java instances conforming to the interface/protocol.

For the Runnable interface used in threading the converse needs to be possible where Java code can call through to Swift code. This is performed using a Java proxy class which has a pointer to the associated Swift object and a "native" implementation of the "run()" method that calls through to Swift. On the Swift side this is surfaced as the "RunnableBase" class which can be subclassed to provide a Swift implementation of the "run()" method callable from Java.

This approach is also taken for processing events and all interfaces with names ending in "Listener", "Manager" or "Handler" also have "Base" classes generated for subclassing along with Java Proxy classes. On macOS and Linux these classes are compiled into a jar file ~/swiftjava.jar using the genjar.sh script for this to work.

    class MyActionListener: ActionListenerBase {
        override func actionPerformed(e event: ActionEvent?) {
            System.exit(0);
        }
    }

    quitButton.addActionListener(MyActionListener());

Any interface/protocol from a Java interface can be added to a class to enable it to be passed to Java provide it's name ends in Listener. The implementation is a little complex but does not have an appreciable overhead. structs can also be made accesable to Java in this way but the object will no be live i.e. a coy of the struct will be taken.

Some event processing is also done by subclassing concrete classes that have names ending in "Adapter". Slightly modified Swift "Base" classes and Java Proxies are also generated for this. Other classes have methods that are intended to be responsibility of the subclasses such as java.awt.Canvas.paint(). A list of these methods needs to be maintained in the code generator unfortunately. If one of these methods encountered a Base class and Proxy is generated for the concrete class that can be subclassed.

As these "Base" subclasses can't close over variables in your program you may want to have an initialiser to capture these instead. There is a bit of a standard dance that needs to be performed. Instantiate the "Base" superclass and assign it's javaObject to your classes' javaObject. Due to the use of generics you'll also be prompted to provide a null implementation of the "required" initialiser.

class MyCanvas: CanvasBase {

    init(imageProducer:ImageProducer) {
        super.init(javaObject: nil)
        inherit(CanvasBase())
        image = createImage(imageProducer)
    }

    required init(javaObject: jobject?) {
        fatalError("init(javaObject:) has not been implemented")
    }

    ...

Consult the Swing examples code for further details.

MIT License

The MIT License (MIT) Copyright (c) 2016, John Holdsworth

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

This License does not apply to the code generated from the Apple distribution of the Java VM which are provided under the provisions of "Fair Use" and your use is ultimately subject to the original License Agreement.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].