Import ReactiveCocoa, or PromiseKit, or BrightFutures as sources? - xcode

I have an OSX project (xcode plugin) and I want to use the ReactiveCocoa paradigms in it (PromiseKit andBrightFutures` are the other implementations of the same paradigms so I need to import at least one from these 3 frameworks/libraries).
The problem is it seems impossible to import them as compiled frameworks into my project because it is plugin. In my project I used dispatch_async and dispatch_after functions only but their nested blocks look awful.
The only solution I found is import one from these frameworks as sources but I don't know how to detach their code. So could anybody help with this trouble? Or maybe are there any other similar libraries which are already represented as source files only?

Short Answer:
Use a dependency manager like Cocoapods or Carthage.
Longer Answer: You can do it manually, but even if you don't want to use any of those, you can look at the .podspec file and see how it's supposed to be used. For example BrightFutures.podspec says:
s.source_files = 'BrightFutures/*.swift'
s.dependency 'Result', '0.6.0-beta.6'
That means that you need to import all the .swift files inside the BrightFutures folder, and that it won't work unless you also import the files from another project called Result.
But please, just let the tools do that for you. You'll be happier. :)

Related

Xcode sometimes doesn't require imports at the top of the file

I am faced with a strange issue. I recently rebuilt my Xcode project file using a tool called Xcode gen, I now have hundreds of errors in my files related to imports, for example:
import Foundation
struct BillingHistoryDetailTableCellViewModel {
let contentColor: UIColor?
// Implementation
}
error: Cannot find type 'UIColor' in scope
Why am I suddenly faced with this error now? Xcode had no issue compiling this kind of file before.
Is there some kind of setting or flag required to fix this?
Answering this for others:
If your project happens to include objective-c code and the bridge file includes imports to frameworks that use UIKit then this will be imported globally across your project, hence Xcode not asking for the import in files where you reference objects in UIKit.
This seems kinda like a bad side effect of using an objective c bridge as it's easy to miss the adding the import statements.

Is there a standard practice for splitting packages into modular components?

I'm working on a library with multiple layers of functionality. I want developers to be able to import only the parts they need, ie mylib-core, mylib-feature1, mylib-feature2, etc. Each lives in its own git repo. I'd also like to provide a simple mylib package which exposes a default set of functionality which is useful for developers new to the library. See d3.js version 4+ for something very similar to what I'm trying to accomplish.
The problems I've run into are
Apparently you can't share a package name between packages. This is a problem because it would be nice to import all the desired repos and then simply have everything available under the mylib name.
I don't see an obvious way to re-export functionality, in order to build the default mylib package.
Are there good solutions or a more idomatic go way to accomplish what I'm shooting for?
Answering your question, there is no idiomatic way of doing what you want. It is common in JavaScript to import a library and export its members without interference. This is not the case in Golang.
I advise you to host your whole library under a single repo, and split the functionality to packages. The Go compiler will only compile and use the imported packages.
And a tip for the future, Go is very different than almost any other language you previously know 😅

Dividing a Swift application's components into Swift modules

I'm writing an iOS application in Swift, and I'm trying to figure out how to organize the project into separate modules. I'm using an MVVM architecture, and I want to make the Model, ViewModel, and View components separate Swift modules that make only subsets of themselves accessible to the modules that import them. The files in the View would import the ViewModel, and files in the ViewModel would import the Model. How can I accomplish this? Note that I'm not trying to create libraries that multiple applications can share. I'm just trying to enforce separation of components using modules.
EDIT: Maybe the question is, "What mechanism should I use to create modules aside from the one that comes with the initial iOS application project?"
One of the answers in "How do you use Namespaces in Swift?" https://stackoverflow.com/a/24032860/215400 says, "classes (etc) are implicitly scoped by the module (Xcode target) they are in." From that, one might conclude that targets correspond to modules and that the answer is to create separate targets within an Xcode project, but I tried that earlier, and tskulbru is saying that I need multiple Xcode projects.
Regarding multiple Xcode projects, the File > New > Project > iOS Framework & Library > Cocoa Touch Framework option didn't look right because it's supposed to be for things that use UIKit, and two of the modules I want to create shouldn't depend on UIKit. The other "Framework & Library" option, Cocoa Touch static library, isn't an option with Swift.
Another StackOverflow post mentioned using private Pods. After spending an hour working on that, I concluded that it wasn't the right solution because I shouldn't have to edit these modules in different workspaces.
This isn't possible without creating separate projects for the modules you want to create. This is because the way Swift handles namespacing.
Eonil answered this better than me: https://stackoverflow.com/a/24032860/215400
(Copy below)
Answered by SevenTenEleven in the Apple dev forum:
Namespaces are not per-file; they're per-target (based on the
"Product Module Name" build setting). So you'd end up with something
like this:
import FrameworkA
import FrameworkB
FrameworkA.foo()
All Swift declarations are considered to be part of
some module, so even when you say "NSLog" (yes, it still exists)
you're getting what Swift thinks of as "Foundation.NSLog".
Also Chris Lattner tweeted about namespacing.
Namespacing is implicit in swift, all classes (etc) are implicitly
scoped by the module (Xcode target) they are in. no class prefixes
needed
From my perspective if you want to encapsulate your components, probably you have two solutions:
Framework
Internal cocoapods
Both solutions will give you fully encapsulated modules, where you can define API that will be available in project through public keyword.
All other things will be not visible in your core project.
Managing your project will cost you a lot more time, but if you write this using SOLID principles, probably you will get more reusable code and those frameworks could be imported to other project just using import definition.

Tracing source to binary

I'm trying to understand the way a particular package fits into a project I'm working on. I believe only a portion of this package actually makes it into the binary of the project, and I need to find out exactly which parts. Library functions from this package are called from many other places (i.e. several other packages depend on it).
I plan to build the project and distribute it. Is the only way to determine which source->binary files I'll distribute by looking at all of the headers in my dependent packages? Or is there a more clever way to approach this?
Thanks in advance,
You haven't given us much information to go on, but here's a method that will work: remove parts of the package and see if the project will still compile.
Use nm to unpack a static lib. This will list all the files and methods included in the lib.
You could also try using strings.
This displays strings that are defined in the binary.
Look through your source and see if the strings you define are in the library.
Something like gprof could also be used to see which methods are called by your executable.

OSGI: Is it possible Import-package and add a visibility:=reexport?

i would like to import a package rather than require bundle in a manifest and have all bundles that require the former package inherit the imported package. I am assuming that it is possible to set visibility: reexport, but Eclipse does not complain if i had this option...
It's not possible and it's not necessary either. A bundle using Import-Package can simply obtain the package from the original bundle that exports it; there is no need to "route" the dependency through an intermediate bundle.
This is one of the biggest advantages of Import-Package: an importing bundle neither knows nor cares which other bundle(s) it's getting the packages from.
You can only reexport when requiring bundles.
Import-Package should be preferred over Require-Bundle or DynamicImport-Package. The former is only really necessary if you must deal with split packages whereas the latter was only intended to address situations where you didn't know the class name in advance (e.g., SPI-like situations), although it can also be used safely as an optional import-like facility. In general, you should be avoiding things that hide dependencies (e.g., broad dynamic imports) or obscure them (e.g., requiring bundles). The fact that Require-Bundle supports reexporting is a decision that should have never been made and there is no reasonable use case for this feature, all it does it further obscure dependencies and create a tangled mess.
No, it's not possible to reexport a package. For that you will need to use a bundle, or a different class loading strategy.
I'm apparently missing the "reply to comment" link, so forgive me that I'm replying to the question in the comments here...
Whether you are in a "hierarchy" or not doesn't really make a difference. First bundles are used in different contexts, so they won't always be used in a container that knows that they want. Second, a bundle still doesn't use everything available to it in a "hierarchy", so acting it does just leads to dependency fan out, since the real dependencies are hidden.
I am not sure what your problem is. If you do not want to require a bundle, you have to import all packages you need. To generate this list you can use the maven-bundle-plugin (for maven projects). If you do not want to generate the concrete list of needed imports, than you can try
DynamicImport-Package: *
which should import the needed packages on demand.

Resources