Creating a custom framework which uses RealmSwift - ios

When using realm in a simple project, I used the following steps from realm's instructions:
Download the latest release of Realm and extract the zip.
Go to your Xcode project’s “General” settings. Drag RealmSwift.framework and Realm.framework from the appropriate
Swift-versioned directory for your project in ios/, osx/, tvos/ or
watchos/ directory to the “Embedded Binaries” section. Make sure Copy
items if needed is selected (except if using Realm on multiple
platforms in your project) and click Finish.
In your unit test target’s “Build Settings”, add the parent path to RealmSwift.framework in the “Framework Search Paths” section.
If using Realm in an iOS, tvOS or watchOS project, create a new “Run Script Phase” in your app’s target’s “Build Phases” and paste the
following snippet in the script text field:
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework/strip-frameworks.sh"
I need to create a custom framework so that I can share multiple classes between apps. These classes use the Realm and RealmSwift Framework.
So I created a custom framework and added some classes. For these classes to work however, I need to have a link to the Realm framework within my custom framework.
I'm unsure how this can be done as in step 2, it states to drag the Realm and RealmSwift frameworks into the 'embedded section' of the project's general settings. But with a framework project, there is no embedded section. There is the 'Linked Frameworks and Libraries' section. I dragged the realm and realmSwift frameworks in there instead. But the custom framework will not build and it says that no module could be found for RealmSwift.
I'm unsure in a framework project if the search paths are the same as what they would be with a regular xcode project ( i.e. $(PROJECT_DIR) ) and I'm unsure what level I should expect to see the Realm and RealmSwift frameworks in my project explorer.

It's very annoying working with framework and library, if your framework is not packed into a .framework, then you might do something like this, might work:
Create a folder for your framework, add some source files
Add a .podspec with dependencies is Realm and RealmSwift, other value then you can learn from other pod
Create a normal app project
Install your framework into that app project with cocoapods with :path point to your folder, this will install realm and realmswift along with it
Now you can code your framework with realm normally without hard linking
For cocoapods and framework related stuff, check this tutorial
For framework project, what i usually do is avoid packing third party lib/framework into my .framework, i have 2 solution for this:
Let user does the job, mean you will create completion block and let them save it to realm themselve
Only include headers of the third party lib into your project and hope it will build without source files, this only works with simple third party project that have few headers, probably not Realm

Related

adding RealmSwift to Cocoa Touch Framework: missing required modules

I try to include RealmSwift into a Cocoa Touch Framework: I dragged RealmSwift.framework into my Xcode project and added it to "Linked Framwork and Libraries".
I also added $(PROJECT_DIR)/MyProject/RealmSwift.framework/Frameworks to the Framework Search Paths but I still get the error:
Missing required modules: Realm.Private, Realm
What am I missing here?
Per Realm's documentation on using Realm Swift's prebuilt dynamic frameworks, you need to ensure that both Realm.framework and RealmSwift.framework are added to your Xcode project, can be found on the framework search path, and are configured to be linked by the targets that use Realm Swift. It's not necessary for RealmSwift.framework/Frameworks to be on the framework search path, only the directory containing RealmSwift.framework.

Realm: bcsymbolmap is missing from working copy

I'm trying to include Realm 2.0.3 and RealmSwift 2.0.3 iOS Swift 2.3 as dynamic framework binaries in my project. I find that they take too long to compile.
I'm able to build my project and run it in the simulator just fine, but when I archive I'm receiving this error:
This is how I'm including the frameworks (simply drag and drop into project):
Help!
Per #TiM's suggestion, in the target's Build Phases I made sure that the two dynamic frameworks are added in in these sections:
Link Binary with Library
Embed Frameworks
Dragging and dropping the frameworks in the project does NOT automatically add them to Embed Framworks

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)

How to create an Xcode project that is not an app but is visible in other projects?

I want to create a project with a handful of categories that add useful functionality to UIKit.
I want to keep this as a separate project so that it can be source-controlled separately (and eventually hosted on github, and downloadable as a dependency via cocoa pods...but let's skip this for now.)
But all the Xcode 6.1 project templates imply an app inside. When I select an empty project it complains about missing base SDK. But this cannot be set without a target present. It is quite confusing. I don't need a target. Do I?
The project should be just a shell for a number of categories + a accompanying summary header file.
I want to be able to drag this project as a subproject to any other proper app project, import the summary header file and expose those categories to the main project.
Any advice?
You need a target. Every source file that should be compiled must be a part of a target.
You could reference each source file from the target(s) in your app's Xcode projects, but that'd be tedious as you'd have to add to every project manually when you add source to your shared repository.
Either create an embedded framework project or a static library. Unless you are really going to share code between an app and an app's extension, go with the static library. It is a lot easier to manage.
Create a project that has a static library target, add the files to that static library.
Then create a workspace that has your static library project and your app(s) project(s) in it. Modify the app targets to link against the static library.

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.

Resources