├── .gitignore
├── android
├── .gitignore
├── .idea
│ ├── .name
│ ├── codeStyles
│ │ ├── Project.xml
│ │ └── codeStyleConfig.xml
│ ├── gradle.xml
│ ├── jarRepositories.xml
│ ├── misc.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── rogchap
│ │ │ └── foobar
│ │ │ └── ExampleInstrumentedTest.kt
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── cpp
│ │ │ ├── CMakeLists.txt
│ │ │ └── native-lib.cpp
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── rogchap
│ │ │ │ └── foobar
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v24
│ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── drawable
│ │ │ └── ic_launcher_background.xml
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── rogchap
│ │ └── foobar
│ │ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── go
├── Makefile
├── clangwrap.sh
├── cmd
│ └── libfoo
│ │ └── main.go
├── foo
│ └── foo.go
└── go.mod
└── ios
├── foobar.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── foobar
├── AppDelegate.swift
├── Assets.xcassets
├── AppIcon.appiconset
│ └── Contents.json
└── Contents.json
├── Base.lproj
└── LaunchScreen.storyboard
├── ContentView.swift
├── Info.plist
├── Preview Content
└── Preview Assets.xcassets
│ └── Contents.json
├── SceneDelegate.swift
└── foobar-Bridging-Header.h
/.gitignore:
--------------------------------------------------------------------------------
1 | xcuserdata
2 | lib
3 | jniLibs
4 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/android/.idea/.name:
--------------------------------------------------------------------------------
1 | foobar
--------------------------------------------------------------------------------
/android/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | xmlns:android
17 |
18 | ^$
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | xmlns:.*
28 |
29 | ^$
30 |
31 |
32 | BY_NAME
33 |
34 |
35 |
36 |
37 |
38 |
39 | .*:id
40 |
41 | http://schemas.android.com/apk/res/android
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | .*:name
51 |
52 | http://schemas.android.com/apk/res/android
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | name
62 |
63 | ^$
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | style
73 |
74 | ^$
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | .*
84 |
85 | ^$
86 |
87 |
88 | BY_NAME
89 |
90 |
91 |
92 |
93 |
94 |
95 | .*
96 |
97 | http://schemas.android.com/apk/res/android
98 |
99 |
100 | ANDROID_ATTRIBUTE_ORDER
101 |
102 |
103 |
104 |
105 |
106 |
107 | .*
108 |
109 | .*
110 |
111 |
112 | BY_NAME
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/android/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
21 |
--------------------------------------------------------------------------------
/android/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/android/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | android {
6 | compileSdkVersion 30
7 | buildToolsVersion "30.0.1"
8 |
9 | defaultConfig {
10 | applicationId "com.rogchap.foobar"
11 | minSdkVersion 21
12 | targetSdkVersion 30
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | externalNativeBuild {
18 | cmake {
19 | cppFlags ""
20 | }
21 | }
22 | }
23 |
24 | buildTypes {
25 | release {
26 | minifyEnabled false
27 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
28 | }
29 | }
30 | externalNativeBuild {
31 | cmake {
32 | path "src/main/cpp/CMakeLists.txt"
33 | version "3.10.2"
34 | }
35 | }
36 | }
37 |
38 | dependencies {
39 | implementation fileTree(dir: "libs", include: ["*.jar"])
40 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
41 | implementation 'androidx.core:core-ktx:1.3.1'
42 | implementation 'androidx.appcompat:appcompat:1.2.0'
43 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
44 | testImplementation 'junit:junit:4.12'
45 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
46 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/android/app/src/androidTest/java/com/rogchap/foobar/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.rogchap.foobar
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.rogchap.foobar", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/android/app/src/main/cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | # Creates and names a library, sets it as either STATIC
9 | # or SHARED, and provides the relative paths to its source code.
10 | # You can define multiple libraries, and CMake builds them for you.
11 | # Gradle automatically packages shared libraries with your APK.
12 |
13 | add_library( # Sets the name of the library.
14 | native-lib
15 |
16 | # Sets the library as a shared library.
17 | SHARED
18 |
19 | # Provides a relative path to your source file(s).
20 | native-lib.cpp )
21 |
22 | add_library(lib_foo SHARED IMPORTED)
23 | set_property(TARGET lib_foo PROPERTY IMPORTED_NO_SONAME 1)
24 | set_target_properties(lib_foo PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libfoo.so)
25 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/)
26 |
27 | # Searches for a specified prebuilt library and stores the path as a
28 | # variable. Because CMake includes system libraries in the search path by
29 | # default, you only need to specify the name of the public NDK library
30 | # you want to add. CMake verifies that the library exists before
31 | # completing its build.
32 |
33 | find_library( # Sets the name of the path variable.
34 | log-lib
35 |
36 | # Specifies the name of the NDK library that
37 | # you want CMake to locate.
38 | log )
39 |
40 | # Specifies libraries CMake should link to your target library. You
41 | # can link multiple libraries, such as libraries you define in this
42 | # build script, prebuilt third-party libraries, or system libraries.
43 |
44 | target_link_libraries( # Specifies the target library.
45 | native-lib
46 |
47 | lib_foo
48 |
49 | # Links the target library to the log library
50 | # included in the NDK.
51 | ${log-lib} )
--------------------------------------------------------------------------------
/android/app/src/main/cpp/native-lib.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "libfoo.h"
5 |
6 | extern "C" {
7 | jstring
8 | Java_com_rogchap_foobar_MainActivity_reverse(JNIEnv* env, jobject, jstring str) {
9 | const char* cstr = env->GetStringUTFChars(str, 0);
10 | char* cout = reverse(const_cast(cstr));
11 | jstring out = env->NewStringUTF(cout);
12 | env->ReleaseStringUTFChars(str, cstr);
13 | free(cout);
14 | return out;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/rogchap/foobar/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.rogchap.foobar
2 |
3 | import androidx.appcompat.app.AppCompatActivity
4 | import android.os.Bundle
5 | import kotlinx.android.synthetic.main.activity_main.*
6 |
7 | class MainActivity : AppCompatActivity() {
8 |
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | setContentView(R.layout.activity_main)
12 |
13 | btn.setOnClickListener {
14 | txt.setText(reverse(txt.text.toString()))
15 | }
16 | }
17 |
18 | /**
19 | * A native method that is implemented by the 'native-lib' native library,
20 | * which is packaged with this application.
21 | */
22 | private external fun reverse(str: String): String
23 |
24 | companion object {
25 | // Used to load the 'native-lib' library on application startup.
26 | init {
27 | System.loadLibrary("native-lib")
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/android/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
23 |
24 |
35 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | foobar
3 | Reverse
4 | Text to reverse
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/test/java/com/rogchap/foobar/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.rogchap.foobar
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext.kotlin_version = "1.3.72"
4 | repositories {
5 | google()
6 | jcenter()
7 | }
8 | dependencies {
9 | classpath "com.android.tools.build:gradle:4.0.1"
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | }
22 | }
23 |
24 | task clean(type: Delete) {
25 | delete rootProject.buildDir
26 | }
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rogchap/libfoo/e97c64a25dfa2626f30df27bef4fc70dada57091/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Sep 12 14:53:37 AEST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | rootProject.name = "foobar"
--------------------------------------------------------------------------------
/go/Makefile:
--------------------------------------------------------------------------------
1 | IOS_OUT=lib/ios
2 |
3 | ios-arm64:
4 | CGO_ENABLED=1 \
5 | GOOS=darwin \
6 | GOARCH=arm64 \
7 | SDK=iphoneos \
8 | CC=$(shell go env GOROOT)/misc/ios/clangwrap.sh \
9 | CGO_CFLAGS="-fembed-bitcode" \
10 | go build -buildmode=c-archive -tags ios -o $(IOS_OUT)/arm64.a ./cmd/libfoo
11 |
12 | ios-x86_64:
13 | CGO_ENABLED=1 \
14 | GOOS=darwin \
15 | GOARCH=amd64 \
16 | SDK=iphonesimulator \
17 | CC=$(PWD)/clangwrap.sh \
18 | go build -buildmode=c-archive -tags ios -o $(IOS_OUT)/x86_64.a ./cmd/libfoo
19 |
20 | ios: ios-arm64 ios-x86_64
21 | lipo $(IOS_OUT)/x86_64.a $(IOS_OUT)/arm64.a -create -output $(IOS_OUT)/foo.a
22 | cp $(IOS_OUT)/arm64.h $(IOS_OUT)/foo.h
23 |
24 |
25 | ANDROID_OUT=../android/app/src/main/jniLibs
26 | ANDROID_SDK=$(HOME)/Library/Android/sdk
27 | NDK_BIN=$(ANDROID_SDK)/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/bin
28 |
29 | android-armv7a:
30 | CGO_ENABLED=1 \
31 | GOOS=android \
32 | GOARCH=arm \
33 | GOARM=7 \
34 | CC=$(NDK_BIN)/armv7a-linux-androideabi21-clang \
35 | go build -buildmode=c-shared -o $(ANDROID_OUT)/armeabi-v7a/libfoo.so ./cmd/libfoo
36 |
37 | android-arm64:
38 | CGO_ENABLED=1 \
39 | GOOS=android \
40 | GOARCH=arm64 \
41 | CC=$(NDK_BIN)/aarch64-linux-android21-clang \
42 | go build -buildmode=c-shared -o $(ANDROID_OUT)/arm64-v8a/libfoo.so ./cmd/libfoo
43 |
44 | android-x86:
45 | CGO_ENABLED=1 \
46 | GOOS=android \
47 | GOARCH=386 \
48 | CC=$(NDK_BIN)/i686-linux-android21-clang \
49 | go build -buildmode=c-shared -o $(ANDROID_OUT)/x86/libfoo.so ./cmd/libfoo
50 |
51 | android-x86_64:
52 | CGO_ENABLED=1 \
53 | GOOS=android \
54 | GOARCH=amd64 \
55 | CC=$(NDK_BIN)/x86_64-linux-android21-clang \
56 | go build -buildmode=c-shared -o $(ANDROID_OUT)/x86_64/libfoo.so ./cmd/libfoo
57 |
58 | android: android-armv7a android-arm64 android-x86 android-x86_64
59 |
60 |
--------------------------------------------------------------------------------
/go/clangwrap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
4 | CLANG=`xcrun --sdk $SDK --find clang`
5 |
6 | if [ "$GOARCH" == "amd64" ]; then
7 | CARCH="x86_64"
8 | elif [ "$GOARCH" == "arm64" ]; then
9 | CARCH="arm64"
10 | fi
11 |
12 | exec $CLANG -arch $CARCH -isysroot $SDK_PATH -mios-version-min=10.0 "$@"
13 |
14 |
--------------------------------------------------------------------------------
/go/cmd/libfoo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "C"
4 |
5 | import (
6 | "rogchap.com/libfoo/foo"
7 | )
8 |
9 | //export reverse
10 | func reverse(str *C.char) *C.char {
11 | return C.CString(foo.Reverse(C.GoString(str)))
12 | }
13 |
14 | func main() {}
15 |
--------------------------------------------------------------------------------
/go/foo/foo.go:
--------------------------------------------------------------------------------
1 | package foo
2 |
3 | // Reverse reverses the given string by each utf8 character
4 | func Reverse(in string) string {
5 | n := 0
6 | rune := make([]rune, len(in))
7 | for _, r := range in {
8 | rune[n] = r
9 | n++
10 | }
11 | rune = rune[0:n]
12 | for i := 0; i < n/2; i++ {
13 | rune[i], rune[n-1-i] = rune[n-1-i], rune[i]
14 | }
15 | return string(rune)
16 | }
17 |
--------------------------------------------------------------------------------
/go/go.mod:
--------------------------------------------------------------------------------
1 | module rogchap.com/libfoo
2 |
3 | go 1.15
4 |
--------------------------------------------------------------------------------
/ios/foobar.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | DB07600224FE19EE003BBA2B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB07600124FE19EE003BBA2B /* AppDelegate.swift */; };
11 | DB07600424FE19EE003BBA2B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB07600324FE19EE003BBA2B /* SceneDelegate.swift */; };
12 | DB07600624FE19EE003BBA2B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB07600524FE19EE003BBA2B /* ContentView.swift */; };
13 | DB07600824FE19EF003BBA2B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB07600724FE19EF003BBA2B /* Assets.xcassets */; };
14 | DB07600B24FE19EF003BBA2B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB07600A24FE19EF003BBA2B /* Preview Assets.xcassets */; };
15 | DB07600E24FE19EF003BBA2B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB07600C24FE19EF003BBA2B /* LaunchScreen.storyboard */; };
16 | DBB6D212250C8F0100829B2E /* foo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBB6D210250C8F0100829B2E /* foo.a */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | DB075FFE24FE19EE003BBA2B /* foobar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = foobar.app; sourceTree = BUILT_PRODUCTS_DIR; };
21 | DB07600124FE19EE003BBA2B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
22 | DB07600324FE19EE003BBA2B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
23 | DB07600524FE19EE003BBA2B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
24 | DB07600724FE19EF003BBA2B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
25 | DB07600A24FE19EF003BBA2B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
26 | DB07600D24FE19EF003BBA2B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
27 | DB07600F24FE19EF003BBA2B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
28 | DB1656A924FF52D7008DA4B8 /* foobar-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "foobar-Bridging-Header.h"; sourceTree = ""; };
29 | DBB6D210250C8F0100829B2E /* foo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = foo.a; path = ../go/lib/ios/foo.a; sourceTree = ""; };
30 | DBB6D211250C8F0100829B2E /* foo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = foo.h; path = ../go/lib/ios/foo.h; sourceTree = ""; };
31 | /* End PBXFileReference section */
32 |
33 | /* Begin PBXFrameworksBuildPhase section */
34 | DB075FFB24FE19ED003BBA2B /* Frameworks */ = {
35 | isa = PBXFrameworksBuildPhase;
36 | buildActionMask = 2147483647;
37 | files = (
38 | DBB6D212250C8F0100829B2E /* foo.a in Frameworks */,
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXFrameworksBuildPhase section */
43 |
44 | /* Begin PBXGroup section */
45 | DB075FF524FE19ED003BBA2B = {
46 | isa = PBXGroup;
47 | children = (
48 | DB07600024FE19EE003BBA2B /* foobar */,
49 | DB075FFF24FE19EE003BBA2B /* Products */,
50 | DBB6D210250C8F0100829B2E /* foo.a */,
51 | DBB6D211250C8F0100829B2E /* foo.h */,
52 | );
53 | sourceTree = "";
54 | };
55 | DB075FFF24FE19EE003BBA2B /* Products */ = {
56 | isa = PBXGroup;
57 | children = (
58 | DB075FFE24FE19EE003BBA2B /* foobar.app */,
59 | );
60 | name = Products;
61 | sourceTree = "";
62 | };
63 | DB07600024FE19EE003BBA2B /* foobar */ = {
64 | isa = PBXGroup;
65 | children = (
66 | DB1656A924FF52D7008DA4B8 /* foobar-Bridging-Header.h */,
67 | DB07600124FE19EE003BBA2B /* AppDelegate.swift */,
68 | DB07600324FE19EE003BBA2B /* SceneDelegate.swift */,
69 | DB07600524FE19EE003BBA2B /* ContentView.swift */,
70 | DB07600724FE19EF003BBA2B /* Assets.xcassets */,
71 | DB07600C24FE19EF003BBA2B /* LaunchScreen.storyboard */,
72 | DB07600F24FE19EF003BBA2B /* Info.plist */,
73 | DB07600924FE19EF003BBA2B /* Preview Content */,
74 | );
75 | path = foobar;
76 | sourceTree = "";
77 | };
78 | DB07600924FE19EF003BBA2B /* Preview Content */ = {
79 | isa = PBXGroup;
80 | children = (
81 | DB07600A24FE19EF003BBA2B /* Preview Assets.xcassets */,
82 | );
83 | path = "Preview Content";
84 | sourceTree = "";
85 | };
86 | /* End PBXGroup section */
87 |
88 | /* Begin PBXNativeTarget section */
89 | DB075FFD24FE19ED003BBA2B /* foobar */ = {
90 | isa = PBXNativeTarget;
91 | buildConfigurationList = DB07601224FE19EF003BBA2B /* Build configuration list for PBXNativeTarget "foobar" */;
92 | buildPhases = (
93 | DB075FFA24FE19ED003BBA2B /* Sources */,
94 | DB075FFB24FE19ED003BBA2B /* Frameworks */,
95 | DB075FFC24FE19ED003BBA2B /* Resources */,
96 | );
97 | buildRules = (
98 | );
99 | dependencies = (
100 | );
101 | name = foobar;
102 | productName = foobar;
103 | productReference = DB075FFE24FE19EE003BBA2B /* foobar.app */;
104 | productType = "com.apple.product-type.application";
105 | };
106 | /* End PBXNativeTarget section */
107 |
108 | /* Begin PBXProject section */
109 | DB075FF624FE19ED003BBA2B /* Project object */ = {
110 | isa = PBXProject;
111 | attributes = {
112 | LastSwiftUpdateCheck = 1160;
113 | LastUpgradeCheck = 1160;
114 | ORGANIZATIONNAME = rogchap;
115 | TargetAttributes = {
116 | DB075FFD24FE19ED003BBA2B = {
117 | CreatedOnToolsVersion = 11.6;
118 | LastSwiftMigration = 1160;
119 | };
120 | };
121 | };
122 | buildConfigurationList = DB075FF924FE19ED003BBA2B /* Build configuration list for PBXProject "foobar" */;
123 | compatibilityVersion = "Xcode 9.3";
124 | developmentRegion = en;
125 | hasScannedForEncodings = 0;
126 | knownRegions = (
127 | en,
128 | Base,
129 | );
130 | mainGroup = DB075FF524FE19ED003BBA2B;
131 | productRefGroup = DB075FFF24FE19EE003BBA2B /* Products */;
132 | projectDirPath = "";
133 | projectRoot = "";
134 | targets = (
135 | DB075FFD24FE19ED003BBA2B /* foobar */,
136 | );
137 | };
138 | /* End PBXProject section */
139 |
140 | /* Begin PBXResourcesBuildPhase section */
141 | DB075FFC24FE19ED003BBA2B /* Resources */ = {
142 | isa = PBXResourcesBuildPhase;
143 | buildActionMask = 2147483647;
144 | files = (
145 | DB07600E24FE19EF003BBA2B /* LaunchScreen.storyboard in Resources */,
146 | DB07600B24FE19EF003BBA2B /* Preview Assets.xcassets in Resources */,
147 | DB07600824FE19EF003BBA2B /* Assets.xcassets in Resources */,
148 | );
149 | runOnlyForDeploymentPostprocessing = 0;
150 | };
151 | /* End PBXResourcesBuildPhase section */
152 |
153 | /* Begin PBXSourcesBuildPhase section */
154 | DB075FFA24FE19ED003BBA2B /* Sources */ = {
155 | isa = PBXSourcesBuildPhase;
156 | buildActionMask = 2147483647;
157 | files = (
158 | DB07600224FE19EE003BBA2B /* AppDelegate.swift in Sources */,
159 | DB07600424FE19EE003BBA2B /* SceneDelegate.swift in Sources */,
160 | DB07600624FE19EE003BBA2B /* ContentView.swift in Sources */,
161 | );
162 | runOnlyForDeploymentPostprocessing = 0;
163 | };
164 | /* End PBXSourcesBuildPhase section */
165 |
166 | /* Begin PBXVariantGroup section */
167 | DB07600C24FE19EF003BBA2B /* LaunchScreen.storyboard */ = {
168 | isa = PBXVariantGroup;
169 | children = (
170 | DB07600D24FE19EF003BBA2B /* Base */,
171 | );
172 | name = LaunchScreen.storyboard;
173 | sourceTree = "";
174 | };
175 | /* End PBXVariantGroup section */
176 |
177 | /* Begin XCBuildConfiguration section */
178 | DB07601024FE19EF003BBA2B /* Debug */ = {
179 | isa = XCBuildConfiguration;
180 | buildSettings = {
181 | ALWAYS_SEARCH_USER_PATHS = NO;
182 | CLANG_ANALYZER_NONNULL = YES;
183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
184 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
185 | CLANG_CXX_LIBRARY = "libc++";
186 | CLANG_ENABLE_MODULES = YES;
187 | CLANG_ENABLE_OBJC_ARC = YES;
188 | CLANG_ENABLE_OBJC_WEAK = YES;
189 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
190 | CLANG_WARN_BOOL_CONVERSION = YES;
191 | CLANG_WARN_COMMA = YES;
192 | CLANG_WARN_CONSTANT_CONVERSION = YES;
193 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
194 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
195 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
196 | CLANG_WARN_EMPTY_BODY = YES;
197 | CLANG_WARN_ENUM_CONVERSION = YES;
198 | CLANG_WARN_INFINITE_RECURSION = YES;
199 | CLANG_WARN_INT_CONVERSION = YES;
200 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
201 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
202 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
203 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
204 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
205 | CLANG_WARN_STRICT_PROTOTYPES = YES;
206 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
207 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
208 | CLANG_WARN_UNREACHABLE_CODE = YES;
209 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
210 | COPY_PHASE_STRIP = NO;
211 | DEBUG_INFORMATION_FORMAT = dwarf;
212 | ENABLE_STRICT_OBJC_MSGSEND = YES;
213 | ENABLE_TESTABILITY = YES;
214 | GCC_C_LANGUAGE_STANDARD = gnu11;
215 | GCC_DYNAMIC_NO_PIC = NO;
216 | GCC_NO_COMMON_BLOCKS = YES;
217 | GCC_OPTIMIZATION_LEVEL = 0;
218 | GCC_PREPROCESSOR_DEFINITIONS = (
219 | "DEBUG=1",
220 | "$(inherited)",
221 | );
222 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
223 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
224 | GCC_WARN_UNDECLARED_SELECTOR = YES;
225 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
226 | GCC_WARN_UNUSED_FUNCTION = YES;
227 | GCC_WARN_UNUSED_VARIABLE = YES;
228 | IPHONEOS_DEPLOYMENT_TARGET = 13.6;
229 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
230 | MTL_FAST_MATH = YES;
231 | ONLY_ACTIVE_ARCH = YES;
232 | SDKROOT = iphoneos;
233 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
234 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
235 | };
236 | name = Debug;
237 | };
238 | DB07601124FE19EF003BBA2B /* Release */ = {
239 | isa = XCBuildConfiguration;
240 | buildSettings = {
241 | ALWAYS_SEARCH_USER_PATHS = NO;
242 | CLANG_ANALYZER_NONNULL = YES;
243 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
244 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
245 | CLANG_CXX_LIBRARY = "libc++";
246 | CLANG_ENABLE_MODULES = YES;
247 | CLANG_ENABLE_OBJC_ARC = YES;
248 | CLANG_ENABLE_OBJC_WEAK = YES;
249 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
250 | CLANG_WARN_BOOL_CONVERSION = YES;
251 | CLANG_WARN_COMMA = YES;
252 | CLANG_WARN_CONSTANT_CONVERSION = YES;
253 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
255 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
256 | CLANG_WARN_EMPTY_BODY = YES;
257 | CLANG_WARN_ENUM_CONVERSION = YES;
258 | CLANG_WARN_INFINITE_RECURSION = YES;
259 | CLANG_WARN_INT_CONVERSION = YES;
260 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
261 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
262 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
263 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
264 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
265 | CLANG_WARN_STRICT_PROTOTYPES = YES;
266 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
267 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
268 | CLANG_WARN_UNREACHABLE_CODE = YES;
269 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
270 | COPY_PHASE_STRIP = NO;
271 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
272 | ENABLE_NS_ASSERTIONS = NO;
273 | ENABLE_STRICT_OBJC_MSGSEND = YES;
274 | GCC_C_LANGUAGE_STANDARD = gnu11;
275 | GCC_NO_COMMON_BLOCKS = YES;
276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
278 | GCC_WARN_UNDECLARED_SELECTOR = YES;
279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
280 | GCC_WARN_UNUSED_FUNCTION = YES;
281 | GCC_WARN_UNUSED_VARIABLE = YES;
282 | IPHONEOS_DEPLOYMENT_TARGET = 13.6;
283 | MTL_ENABLE_DEBUG_INFO = NO;
284 | MTL_FAST_MATH = YES;
285 | SDKROOT = iphoneos;
286 | SWIFT_COMPILATION_MODE = wholemodule;
287 | SWIFT_OPTIMIZATION_LEVEL = "-O";
288 | VALIDATE_PRODUCT = YES;
289 | };
290 | name = Release;
291 | };
292 | DB07601324FE19EF003BBA2B /* Debug */ = {
293 | isa = XCBuildConfiguration;
294 | buildSettings = {
295 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
296 | CLANG_ENABLE_MODULES = YES;
297 | CODE_SIGN_STYLE = Automatic;
298 | DEVELOPMENT_ASSET_PATHS = "\"foobar/Preview Content\"";
299 | DEVELOPMENT_TEAM = V826467GB6;
300 | ENABLE_PREVIEWS = YES;
301 | INFOPLIST_FILE = foobar/Info.plist;
302 | IPHONEOS_DEPLOYMENT_TARGET = 13.7;
303 | LD_RUNPATH_SEARCH_PATHS = (
304 | "$(inherited)",
305 | "@executable_path/Frameworks",
306 | );
307 | LIBRARY_SEARCH_PATHS = (
308 | "$(inherited)",
309 | "$(PROJECT_DIR)",
310 | );
311 | PRODUCT_BUNDLE_IDENTIFIER = com.roghcap.foobar;
312 | PRODUCT_NAME = "$(TARGET_NAME)";
313 | SWIFT_OBJC_BRIDGING_HEADER = "foobar/foobar-Bridging-Header.h";
314 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
315 | SWIFT_VERSION = 5.0;
316 | TARGETED_DEVICE_FAMILY = "1,2";
317 | };
318 | name = Debug;
319 | };
320 | DB07601424FE19EF003BBA2B /* Release */ = {
321 | isa = XCBuildConfiguration;
322 | buildSettings = {
323 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
324 | CLANG_ENABLE_MODULES = YES;
325 | CODE_SIGN_STYLE = Automatic;
326 | DEVELOPMENT_ASSET_PATHS = "\"foobar/Preview Content\"";
327 | DEVELOPMENT_TEAM = V826467GB6;
328 | ENABLE_PREVIEWS = YES;
329 | INFOPLIST_FILE = foobar/Info.plist;
330 | IPHONEOS_DEPLOYMENT_TARGET = 13.7;
331 | LD_RUNPATH_SEARCH_PATHS = (
332 | "$(inherited)",
333 | "@executable_path/Frameworks",
334 | );
335 | LIBRARY_SEARCH_PATHS = (
336 | "$(inherited)",
337 | "$(PROJECT_DIR)",
338 | );
339 | PRODUCT_BUNDLE_IDENTIFIER = com.roghcap.foobar;
340 | PRODUCT_NAME = "$(TARGET_NAME)";
341 | SWIFT_OBJC_BRIDGING_HEADER = "foobar/foobar-Bridging-Header.h";
342 | SWIFT_VERSION = 5.0;
343 | TARGETED_DEVICE_FAMILY = "1,2";
344 | };
345 | name = Release;
346 | };
347 | /* End XCBuildConfiguration section */
348 |
349 | /* Begin XCConfigurationList section */
350 | DB075FF924FE19ED003BBA2B /* Build configuration list for PBXProject "foobar" */ = {
351 | isa = XCConfigurationList;
352 | buildConfigurations = (
353 | DB07601024FE19EF003BBA2B /* Debug */,
354 | DB07601124FE19EF003BBA2B /* Release */,
355 | );
356 | defaultConfigurationIsVisible = 0;
357 | defaultConfigurationName = Release;
358 | };
359 | DB07601224FE19EF003BBA2B /* Build configuration list for PBXNativeTarget "foobar" */ = {
360 | isa = XCConfigurationList;
361 | buildConfigurations = (
362 | DB07601324FE19EF003BBA2B /* Debug */,
363 | DB07601424FE19EF003BBA2B /* Release */,
364 | );
365 | defaultConfigurationIsVisible = 0;
366 | defaultConfigurationName = Release;
367 | };
368 | /* End XCConfigurationList section */
369 | };
370 | rootObject = DB075FF624FE19ED003BBA2B /* Project object */;
371 | }
372 |
--------------------------------------------------------------------------------
/ios/foobar.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/foobar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/foobar/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // foobar
4 | //
5 | // Created by Roger Chapman on 1/9/20.
6 | // Copyright © 2020 rogchap. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/ios/foobar/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/ios/foobar/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/foobar/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ios/foobar/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // foobar
4 | //
5 | // Created by Roger Chapman on 1/9/20.
6 | // Copyright © 2020 rogchap. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 | import UIKit
11 |
12 | struct ContentView: View {
13 |
14 | @State private var txt: String = ""
15 |
16 | var body: some View {
17 | VStack{
18 | TextField("", text: $txt)
19 | .textFieldStyle(RoundedBorderTextFieldStyle())
20 | Button("Reverse"){
21 | let str = reverse(UnsafeMutablePointer(mutating: (self.txt as NSString).utf8String))
22 | self.txt = String.init(cString: str!, encoding: .utf8)!
23 | // don't forget to release the memory to the C string
24 | str?.deallocate()
25 | }
26 | Spacer()
27 | }
28 | .padding(.all, 15)
29 | }
30 | }
31 |
32 | struct ContentView_Previews: PreviewProvider {
33 | static var previews: some View {
34 | ContentView()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ios/foobar/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ios/foobar/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/foobar/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // foobar
4 | //
5 | // Created by Roger Chapman on 1/9/20.
6 | // Copyright © 2020 rogchap. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |
22 | // Create the SwiftUI view that provides the window contents.
23 | let contentView = ContentView()
24 |
25 | // Use a UIHostingController as window root view controller.
26 | if let windowScene = scene as? UIWindowScene {
27 | let window = UIWindow(windowScene: windowScene)
28 | window.rootViewController = UIHostingController(rootView: contentView)
29 | self.window = window
30 | window.makeKeyAndVisible()
31 | }
32 | }
33 |
34 | func sceneDidDisconnect(_ scene: UIScene) {
35 | // Called as the scene is being released by the system.
36 | // This occurs shortly after the scene enters the background, or when its session is discarded.
37 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
38 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
39 | }
40 |
41 | func sceneDidBecomeActive(_ scene: UIScene) {
42 | // Called when the scene has moved from an inactive state to an active state.
43 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
44 | }
45 |
46 | func sceneWillResignActive(_ scene: UIScene) {
47 | // Called when the scene will move from an active state to an inactive state.
48 | // This may occur due to temporary interruptions (ex. an incoming phone call).
49 | }
50 |
51 | func sceneWillEnterForeground(_ scene: UIScene) {
52 | // Called as the scene transitions from the background to the foreground.
53 | // Use this method to undo the changes made on entering the background.
54 | }
55 |
56 | func sceneDidEnterBackground(_ scene: UIScene) {
57 | // Called as the scene transitions from the foreground to the background.
58 | // Use this method to save data, release shared resources, and store enough scene-specific state information
59 | // to restore the scene back to its current state.
60 | }
61 |
62 |
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/ios/foobar/foobar-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import "foo.h"
6 |
--------------------------------------------------------------------------------