Cant find the common jar on kotlin multi-platform project - kotlin-multiplatform

I created by own multi-platform project and i have implementations for jvm and ios. Once I build the project it generated 5 jars
Name-jvm.jar
Name-jvm-sources.jar
Name-ios-sources.jar
Name-metadata.jar
Name-metadata-sources.jar
Where Name is the name of my project. But am not able to get Name-common.jar. So when I publish the same to bintray, I cant find Name-common.jar through pom.xml is present.
I there anything wrong with my understanding of the multi-platform builds

Default artifacts names in kotlin multiplatform publications modules are as follows.
if your project is called name, it will have following publications for each target
Common -> name-metadata.jar
JVM -> name-jvm.jar
JS -> name-js.jar (with name.js inside)
Android-> name-android.jar (for release build type) or/and name-android-debug.jar (for debug)
I am not a kotlin/native user but i believe ios would have something like this
ios -> name-ios.klib
e.t.c
So referring to your issue, you can access your module as just name-metadata.jar, or with gradle, com.group.name:name-metadata:${version}
If you are going to use it in another multiplatform project, you can just type the name of the project (i.e. com.group.name:name:${version}) all along. Gradle metadata will resolve it to respective targets

Related

iOS - Xcode module build similar to Android

Android Studio provides module build facility, where different module can be built on its own inside same project. Is there anything similar in Xcode?
Little guide with explanation will be appreciated.
You can create a workspace which can hold multiple projects. You can build each separate project separately and include the required different projects in your final build project. You can run different test codes for different projects also with this approach.

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)

Xcode build process for linking & embedding framework to app in workspace

I've separated some functionality in an app I'm working on into a self-contained framework. Both the framework and the app are included in a workspace. How do I include this framework in my build in a machine-agnostic manner?
What I've been doing is adding the framework to the embedded binaries of my client app, as suggested on a number of posts here on SO. This works nicely until you start work on another machine, at which point the randomly generated 'DerivedData' directory the framework resides in can't be found, and you have to re-create the link. This will become a really tiresome process.
I was considering using CocoaPods for this purpose, but unless I'm reading it wrong, you can't just reference local projects with a podspec; the project needs to reside on a known source / repo.
So basically I'd like to know how people here have forged a multi-project build process that isn't linked to the directory structure of a particular development machine.
So I've found a solution that works. The issue was that my client app project referred to the framework file relative to the project itself.
The minimal steps I took to refer to (and embed) my framework were significantly fewer than some of the solutions I've seen.
In my client app's target (on the General tab), add the framework to the 'Embedded Libraries' section. This will also add a reference to the framework to the Project navigator.
Select the reference added to the Project navigator in step 1, and change it's location to be 'Relative to Built Products'. Optionally move the framework to the 'Frameworks' folder of the client app's project, where the rest of the frameworks live.
This second step ensures the build looks for the framework relative to the build products, rather than relative to something else, whose location may vary between machines / copies of the source.
Actually, you can indeed have private Pods. Most tutorials on how to do this usually keep these private Pods within private repos on GitHub, but you can also host them on another Git (non-GitHub) server.
As for the DerivedData directory issue, it sounds like you are including the framework via a build setting (i.e. something like "-framework ~/Library/Developer/Xcode/DerivedData/MyFramework-$$##$###$#/MyFramework.framework").
You should be able to simply click on the "Build Phases" section of your app's target settings and then the "add" (or "+") button and you'll see your (built via the same workspace) framework or library in that list that you can add. More information can be seen in this Apple documentation.

Xcode: What is a target and scheme in plain language?

Yeah the title says it :-) What do they mean in plain English language? I really don't understand the explanation on Apple's website and I need to rename my target and I'm afraid that nothing works after that..
I've added in Workspace and Project too!
Workspace - Contains one or more projects. These projects usually relate to one another
Project - Contains code and resources, etc. (You'll be used to these!)
Target - Each project has one or more targets.
Each target defines a list of build settings for that project
Each target also defines a list of classes, resources, custom scripts etc to include/ use when building.
Targets are usually used for different distributions of the same project.
For example, my project has two targets, a "normal" build and an "office" build that has extra testing features and may contain several background music tracks and a button to change the track (as it currently does).
You'll be used to adding classes and resources to your default target as you add them.
You can pick and choose which classes / resources are added to which target.
In my example, I have a "DebugHandler" class that is added to my office build
If you add tests, this also adds a new target.
Scheme - A scheme defines what happens when you press "Build", "Test", "Profile", etc.
Usually, each target has at least one scheme
You can autocreate schemes for your targets by going to Scheme > Manage Schemes and pressing "Autocreate Schemes Now"
A target is an end product created by running "build" in Xcode. It might be an app, or a framework, or static library, or a unit test bundle. Whatever it is, it generally corresponds to a single item in the "built products" folder.
A scheme represents a collection of targets that you work with together. It defines which targets are used when you choose various actions in Xcode (Run, Test, Profile, etc.) Often, you will have just one scheme, which uses the main app target for the Run, Archive, and Profile actions, and a unit test target for the Test action. If you were building two related apps, you might have two schemes that used the same unit test bundle but different app targets.
The main benefit of schemes (introduced in Xcode 4) is that they allow you to switch between running your app and your unit tests without needing to toggle the selected target.
I am a visual person, hence to explain the concept I will be using a diagram.
When you have multiple targets they can be one-to-one matched with Xcode's Run,Test,Profile actions, this concept defines a scheme
A target is a version of your Project,i.e targets differ slightly in classes & resources to use during built time. A project can have multiple built time setting for separate distribution requirements.
Xcode structure
Workspace
-> Project
-> Target
-> Dependency
-> Scheme
-> Action
-> Build Configuration
-> Build Configuration File(.xcconfig)
Workspace (.xcworkspace) - is a container of multiple projects. It was created as a next step of cross-project references[About]
Workspace contains all schemes from included projects
Workspace handles all implicit dependencies[About]
Observations:
It is safe to work with different projects inside the same workspace and do not catch
//if you try to open two projects on two Xcode instances
Couldn't load Project.xcodeproj because it is already opened from another project or workspace
Cocoapods[About] working with workspace where creates Pods project
Project (.xcodeproj) - It is a container for targets and scheme. It defines code files, resources...
Also Projects manages Build Configuration(changed by scheme) and Build Configuration File[About]
You can convert existing Project into Workspace
File -> Save As Workspace...
[Workspace vs Project]
Target - PBXNativeTarget section. Defines a specific set of build settings that generate:
Application target
Library and framework targets
Test
Aggregate[About]. E.g. it is used to create a Universal framework or Umbrella framework
Scheme
Contains action(run, test, profile, analyze, archive) + configuration(additional arguments, [Build Configuration], diagnostic)
Scheme can be shared which helps you in CI, Carthage[Example]... and located:
<project_path>/<project_name>.xcodeproj/xcshareddata/xcschemes
Dependency - Targets can have dependencies. Dependency is a source link against. These dependencies can be linked statically or dynamically[About] There are two types of them:
Explicit Dependency[About] - Source code of the dependency that is located in the same project or nested project
Implicit Dependency[About] - Source/closed code of the dependency that is located in the project that is a part of the same workspace.
[Vocabulary]
tldr; Targets contain instructions to build a module/framework/library or an App/end Product e.g. instructions to build a watchOS app and an iOS App. Schemes know how to respond to certain actions e.g. a build action or test action or archive action.
Make sure you See WWDC16 video — Introduction to Xcode [45:13]. If you wanted to gain deeper knowledge then watch the entirety of the video. The video is simple to follow yet very foundational. My answer is mostly off of that.
Scheme
A scheme is how you specify what you want to run and it also contains
information about how you want to run it.
For example, I could have a project with an iOS app and a Watch app,
and in that case, I would have one scheme to run my iOS app and one
scheme to run my Watch app
Run will run my app in the debugger.
Test will run my tests.
Profile will run my app in instruments so I can measure its
performance.
Analyze will run Xcode's static analyzer and help catch problems I
might otherwise have missed.
And finally, the Archive action will build my app for release and put
it in the archive that I can then use to distribute to my testers or
to the App Store or to save for future crash log de-symbolication, or
symbolication.
Project
A project is a document that you use to organize your code an
resources in Xcode.
You have references to source code files and resource files on disc,
targets which actually build those files into products like your app,
Build settings which configure how your targets build their products,
and schemes which configure how you perform actions, such as Run, with
your targets.
Now, to access your project settings, you select your project in the
navigator, you select the popover at the top of the editor, and select
your project there.
Target
You have references to source code files and resource files on disc,
targets which actually build those files into products like your app,
Build settings which configure how your targets build their products,
and schemes which configure how you perform actions, such as Run [test, build], with
your targets.
A target contains the instructions to build one thing like an app or a
framework.
The thing that your target produces is called its product. The set of
steps that your target takes to build its product are called build
phases.
And lastly, a target has Build settings to configure how it builds its
product.
Now, one thing to note is that both projects and targets have Build
settings, and targets inherit the value set at the project level but
can override them with a target-specific value.
A target's build phases do things like cause dependencies to build
first, compile the source files in that target, and link the target
against libraries and frameworks.
To summarize:
Targets
Helps put a set of files together to build/run a product/module/package
Usually it ends up just being a product you ship to app store.
But often it can be a module that you just run unit-tests against it.
Like a single app can have an iOS target along with a watchOS target. Or just a single iOS Target. Or a single iOS target along with a test target, etc.
If you go to your target's Build Phase >> Compile Sources you'll see every file that's being built for that target. Example:
To explicitly quote Apple docs:
A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace. A target defines a single product; it organizes the inputs into the build system—the source files and instructions for processing those source files—required to build that product. Projects can contain one or more targets, each of which produces one product.
The instructions for building a product take the form of build settings and build phases, which you can examine and edit in the Xcode project editor. A target inherits the project build settings, but you can override any of the project settings by specifying different settings at the target level. There can be only one active target at a time; the Xcode scheme specifies the active target.
A target and the product it creates can be related to another target. If a target requires the output of another target in order to build, the first target is said to depend upon the second. If both targets are in the same workspace, Xcode can discover the dependency, in which case it builds the products in the required order. Such a relationship is referred to as an implicit dependency. You can also specify explicit target dependencies in your build settings, and you can specify that two targets that Xcode might expect to have an implicit dependency are actually not dependent. For example, you might build both a library and an application that links against that library in the same workspace. Xcode can discover this relationship and automatically build the library first. However, if you actually want to link against a version of the library other than the one built in the workspace, you can create an explicit dependency in your build settings, which overrides this implicit dependency.
Schemes
A given target can be put through different actions.
build
run
test
profile
archive
You can have a scheme that has all the diagnostics enabled (which makes debugging slow) vs. a scheme that doesn't have any. Or a scheme that runs certain performance related tests vs. a scheme that runs both unit-tests and performance tests. You can edit a scheme so that it performs such actions as:
Building multiple targets
Executing scripts before or after any action
Sending emails before or after any action
Running with memory management diagnostics
Producing either a debug or release build for any action.
For more on that see Customizing the build schemes for a project
To put it all together:
Once you hit run, Xcode will look at the selected scheme. It will find its associated target(s). Use the Build Phases of that target and its Build Settings (any Project Settings that isn't overridden by the target settings will get included) to build a product into the selected destination (the destination can be an iPhone simulator or a physical iPhone or watchOS, etc).
AGAIN WATCH THE WWDC VIDEO!
My take:
Target -- a lower abstraction -- various kinds of builds. Each target has its own Build Settings (so if you split into several targets, take care of that huge sheet individually for each target). Targets have a convenient way of including/excluding files, so you can configure the build effectively on a per-file basis.
Scheme -- a higher abstraction -- guides a target through various ways of deployment (Run, Test, Archive). Has modest ways of configuring the build through Environment Parameters, but employs the Build Settings from the target. Creating / editing / deleting schemes is cheaper and easier than targets.
You can have several schemes guiding one target in several different ways.

Duplicate package problem

I am trying to integrate Twitter in my application. I import two .jar files with different names, but one package has the same name in both files. When I compile, it shoes following error.
Description Resource Path Location Type
D:\CustomClasses\ksoap2-j2me-core-prev-2.1.2.jar(org/kxml2/io/KXmlParser.class): Error!: Duplicate definition for 'org.kxml2.io.KXmlParser' found in: org.kxml2.io.KXmlParser
Assuming the two JARs are third party (not platform libraries), you should consider a more sophisticated compilation and packaging step. But before going down this path, check to see whether the JARs you are importing don't come in different forms -- ones that don't embed their dependencies.
Either way, have a step in your compilation to extract just the parts that you need from each JAR.
If you are not using build scripts but use an IDE for everything, set up a build script just to build your customized dependencies JAR.

Resources