Build TensorFlowLite Swift Custom Framework - ios

I need to build TensorFlowLite Swift Framework/cocoapod from the sources and then use it instead of the original framework in one of the Swift projects.
Downloaded the code and followed the instructions in few scenarios but without success:
1) https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/experimental/swift
a) python configure.py
b) CocoaPods developers isn't applicable as it doesn't take the source from the local TensofFlow folder (or I am mistaken?)
c) Bazel developers I do:
bazel build tensorflow/lite/experimental/swift:TensorFlowLite
bazel test tensorflow/lite/experimental/swift:Tests --swiftcopt=-enable-testing
and eventually
generate_xcodeproj.sh --genconfig tensorflow/lite/experimental/swift/TensorFlowLite.tulsiproj:TensorFlowLite --outputfolder ~/path/to/generated/TensorFlowLite.xcodeproj
as a result I get a project with a libtensorflow-lite-experimental-swift-TensorFlowLite.a and few idx files. It compiles and I see the .a file (but both the app and tests don't compile for various reasons) and I don't quite understand how I can use that .a lib with Swift files as there are no module/headers etc. files.
After all these exercises there is TensorFlowLiteSwift.podspec in the root of TensorFlow and in the experimental/Swift folders. It still depends on the TensorFlowLiteC and if I refer to this podspec in another project via path param I can do import TensorFlowLiteC but not import TensorFlowLiteSwift / import TensorFlowLite and I believe the TensorFlowLiteC is still taken from the Internet, not locally.
2) Custom framework path from here:
https://firebase.google.com/docs/ml-kit/ios/use-custom-tflite
Here are few problems:
a) if I try to just use a project with tensorflow_lite.framework added internally then I can't reference TensorFlowLite / TensorFlowLiteC etc. in the Swift file.
b) if I try to follow a route of creating the local pod and reference the pod project then pod install doesn't work because mandatory parameters are not set (used provided example).
I expect to get a Xcode project or workspace which is built from the local TensorFlowFiles and which I can reference from other projects like 'import TensorFlowLiteSwift' or 'import TensorFlowLite'
The problem is that I don't understand even what's the correct route to make it happen.
Thanks.

All right, I figured out the answer here:
build TensorFlowLiteC framework from the root tensorflow folder:
bazel build --config=ios_fat -c opt //tensorflow/lite/experimental/ios:TensorFlowLiteC_framework
The result can be found here: bazel-bin/tensorflow/lite/experimental/ios/TensorFlowLiteC_framework.zip
Unzip the file and add the contents to the new XCode project (in my case it was Swift Single Window App). If you do it via drag'n'drop then XCode will automatically change the Frameworks, libraries and embedded content section, also will modify the Framework paths
Change this setting Build Settings\Linking\Other Linker Flags to -lc++
Done. You can do
import TensorFlowLiteC
and use the source files from the swift folder.

Related

How to create a close source SDK for iOS with other framework dependencies

I have multiple projects that build into XCFramework. For example:
FeatureA.xcframework
FeatureB.xcframework
FeatureC.xcframework
When I build MySDK, it produces a .xcframework with a "frameworks" folder in it. FeatureA, B and C are inside that folder. This means that the frameworks were embeded.
But, when I add MySDK into another project and try to build I get: no such module "FeatureA" OR Could not build "FeatureA" to Objc.
The only way that my test project builds is by adding each .xcframework dependency. I tried using the search paths, but no luck.
I also tried change the modulemap file, but the error describe above continues.
I want to build a SDK, MySDK.xcframework that contains all depencency frameworks. In this way I hope that someone who wants to use my library will only have to import MySDK.xcframework.
What I want is even possible for iOS?

Xcode Swift: how to import a Swift project

I have made an Xcode Swift project ("Project1"). In a new project ("Project2"), I have trouble adding project 1.
I have tried adding project 1 to project 2's build phases (target dependancies, compiled sources, link binary with libraries); didn't work. When adding to the compiled sources, it wouldn't work no matter which option I chose (folder references, groups, copy if needed).
I get no compiler errors at:
import Project1
But when I try to use a class from project 1, I get the error "Use of undeclared type".
I have also tried to following links with no success:
External library usage in xcode
Xcode : Adding a project as a build dependency
Xcode how to add an external project
Both projects are in Swift (iOS).
I'd be very thankful if someone helped me with this issue.
Update: Project 1 is not a framework - it's an iOS app. I need to use some of its classes in project 2. The problem is that project 1 uses the Objective C library Common Crypto via a bridging header. When I manually add project 1 classes into project 2, I get an error ("unresolved identifier") in the project 1 Swift code that uses Common Crypto.
So in a nutshell: I have an iOS app (project 1), which is in Swift but uses Common Crypto via bridging header. When I add a number of classes from project 1 into project 2, it cannot resolve the references (in project 1) to Common Crypto variables.
Assuming Project1is a Framework and Project2 is an application using the framework:
Create a virgin Workspace (Xcode File -> new -> Workspace) named TestWorkspace
From the Finder, drag the Project1.xcodeprojfile to the TestWorkspace
From the Finder, drag the Project2.xcodeprojfile to the TestWorkspace, above Project1
Edit your TestWorkspace schemas Build setup:
Add Project1 and Project2
make sure Project1 is above Project2
Untick "Paralellize Build" to assure Project1 is build first
Build
Select Project2s target -> General
Drag artefact project1.framework(in Productsgroup) to "Linked Framworks and Libraries"
Note: To be visible for the client, all classes and methods in your project1.framework have to be public or open. Finde detailed information in Apples documentation.
Edit: As you have CommonCrypto as a dependency you will have to add the module to your Project2 project instead to solve your issues ( this is the easiest without resorting to an umbrella framework ). Add a run script build phase and include http://pastebin.com/1vmiqffu
-- Credits: Script 'stolen' from: https://github.com/henrinormak/Heimdall
Ok so I'm going to assume here that Project1 actually has a framework as a target. What are the access permissions set on the types you are trying to use?
Here are a couple of catchya's with Swift and frameworks as I encountered them:
You do not have a bridging header, instead your framework includes headers of non-Swift dependencies inside the header file of your framework ( ModuleName.h ). This also means these will be available to whatever project you import them to. As far as I know you need to use a module.modulemap in order to make use of private headers and includes.
All Swift Classes / Structs / Definitions in general are internal by default. It is a very good design choice and it forces you to think about the access rights on every component you write. Keeping things private by default makes it easier to only open stuff that really needs to be open ( public, open ), allowing for easier code maintenance since you know that private things are only accessed within the same context. ( Otherwise: error )
For some more assistance this link might be of help to you on how to do some fundamentals:
your first ios framewok (swift)

Add a framework to an existing project without using cocoapods

I've got an existing project where i want to add the framework called CoreActionSheetPicker from
https://github.com/skywinder/ActionSheetPicker-3.0
The problem is i cant seem to add the framework to my project? when i pull the framework over to my existing project none of the files below is added and when i try to import it says it does not exist
import CoreActionSheetPicker
I want to do this without cocoaPods. What is the steps in order to do such? i'm using swift. Do i first need to create a WorkSpace?
I've just cloned it, and it appears the project file is invalid. You can see this by trying to open it. You should raise the issue with the owner on GitHub, which is how you're supposed to ask questions about projects there. Then you will get feedback directly from the creator or at least someone else who knows about that project.
As for adding a project,
Download the source
Drag the .xcodeproj into your project within Xcode
Add the framework in Build Phases / link binary with libraries
Add it as a Build Phase / target dependency.
Note that at the moment, you should always builds 3rd part libraries with your swift project, and not just include the binary. See here about binary compatibility of frameworks:
https://developer.apple.com/swift/blog/?id=2

How to reuse Swift code in other projects?

I wrote a class in Swift. I want to use this code in two separate iOS app projects that I wrote. Both the shared code and the apps are written in Swift. What is the best way of doing that?
I tried to create both a framework and a library in Swift and then add it as a sub-project to my app. In both cases I could not make the app see the module. I tried to add the shared module to "Target Dependencies" and "Link Binary With Libraries" of the main app's target. No luck - the app still can not see the classes of the shared module.
Using Xcode6 Beta6 at the moment.
Solution
As Konstantin Koval and Heliem pointed out, all I needed is to use public in my class and method declarations, in the shared module. Now all works, both if I use workspace and if I add the module as a subproject.
Update
I just found an excellent easy solution for reusing code between projects in Swift. It is called Carthage (https://github.com/Carthage/Carthage). This is not a plug as I am not affiliated with it in any way, I just really like it. It works in iOS 8+.
Create a new project (iOS Cocoa Touch Framework) for your reusable code
Move your classes to that Framework project
Mark your methods and classes, that should be visible to others as public
Create Workspace.
You can create a workspace on step 1. When you create new Framework project, Xcode will ask you if you want to create new workspace and add that project to workspace. This is the best approach
Add both your project and Framework to the workspace
Select you project target -> General tab. Add Framework and Libraries (add your library here)
When you want to use code from your Library in swift file, import it using import 'LibTargetName'
You can take a more programatic approach by using SWM (Swift Modules): https://github.com/jankuca/swm
It is very similar to npm (node.js package manager) or bower (client-side module manager); you declare your dependencies in a swiftmodule.json file like below. It does not have a central module registry like the two mentioned JS solutions, it only accepts git URLs.
{
"name": "ProjectName",
"dependencies": {
"Dependency": "git://github.com/…/….git"
}
}
…run swm install and have the Dependency module (compiled into a *.swiftmodule binary) ready for import in the .modules/ directory.
import Dependency
And if you prefer to skip Xcode for app development, you can also build your whole app using swm build (more info in the project's readme).
The project is still in early stages but it makes itself useful a lot for me at least. It provides the most clean (and clear) way of creating importable modules.
Here is a video which is very straightforward: http://eonil-observatory.tumblr.com/post/117205738262/a-proper-way-to-add-a-subproject-to-another-xcode
The video is for OS X instead of iOS. But you will get it and figure out the process for iOS.
Let's assume that AppA needs to reused code from SharedProject.
The following process works for me in Xcode 7 Beta:
Create SharedProject. Project type must be Framework instead of Application. You write common code in this project and mark the code as public.
Open AppA in Xcode, open the folder which contains SharedProject in Finder. Drag the .xcodeproj file of SharedProject from Finder and drop it into the root folder of AppA in Xcode Project Navigator.
AppA --> Build Phases --> Link Binary with Libraries. Add SharedProject.
import SharedProject and reuse code from SharedProject!
Edit:
Nowadays I suggest you use Carthage. It's better than the home made solution above.

How do I add this C library to my iOS Xcode 4 project?

I'm trying to add the openjpeg library to my XCode 4 project so that I can compress images taken by the iPhone's camera to jpeg2000.
I built the static library (libopenjpeg.a) using Cmake on OS/X. (I'm guessing this may have been the first error, that it needs to be built by XCode so it's built for iPhone architecture and not OS X).
I have the library added in the Link Binary with Libraries of my target.
The project builds successfully but I can't seem to import any of the headers from the library into any of my Objective-C classes. I've tried manually adding the folder that contains the libopenjpeg header files to the User Header Search Path but that did not seem to do anything.
Any suggestions?
for the simplest solution
Import the head files to you project's source.
You can still build it on the command-line with CMake, you'd just have to modify the CMakeLists.txt file so the right flags are passed when compiling.
However as Gavin indicates, it may be simpler just to drag the header and source files from the library into your Xcode project, and forego the building of a static library.

Resources