In Java, we can build up expressions to be called using ScriptEngine. This is nice for building up frameworks based on a common naming convention. In JavaScript, there is of course eval(). Does Swift have some sort of mechanism for evaluating a string which contains a swift expression? I'm aware that this could be potentially abused; however, it would simplify my present development.
No. Swift is a compiled language, and the runtime doesn't include the compiler. The iOS SDK doesn't provide a way to evaluate run-time Swift code.
You can execute JavaScript using JavaScriptCore, and JavaScriptCore makes it pretty easy to expose Swift objects and functions to the script. Maybe that will help you.
Related
I was wondering if it is possible to write inline in swift in any other language?
From the Objective-C times, there was a possibility to write assembly using macros __asm__(/*Assembly*/);
I know that it's possible to use Objective-C from swift, and in Objective-C you still could wrap anything that was possible before.
I just curious, is there any 'native' support for any other language in the swift compiler?
I want to import a Swift framework called "Beethoven" into Objective-C project. I import this framework via cocoapods.
The problem is that framework is written in pure swift. Since the classes are not subclass of NSObject they can't be used directly in my objC classes.
I am newbie in Swift and intermediate in objC, but I think there may be 2 solutions for that:
1-Modifying the whole library: which is probably not an optimal solution.
2-Using a new class which behaves as an interface between swift framework and my objC code. I think second solution will be a better alternative in terms of time and effort needed.
Actually below given post explains modifying the pure swift classes but I don't know how to apply this in my case.
How to use Swift non-NSObject subclass in Objective-C
As I mentioned I am not a very capable programmer and there may be better solutions for that problem. I would be grateful if someone can help me and suggest the best solution for integrating pure Swift framework into my objC project.
NSObject is usually not the only problem. Swift has many features that are not supported by Objective-C. To name a few: swift value types (struct's), swift enums with attached values. If a library uses any of those, it will not be possible to auto-generate an Objective-C header (.h) for it.
Adapting the code of the library on the spot might work, but it is likely more work long term in case if you ever need to update that library again.
Your 2nd approach sounds better: create a layer that is compatible with Objective-C on top of the library which exports methods that need to be exported with #objc and adapts the types. If you go that way consider making a PR contribution to the original library so that everyone could use it in Objective-C projects, and you share responsibility of updating it when the swift code changes.
The 3rd approach would be actually to rewrite some parts of you app to Swift. That might or might not be easier depending on the size of the part of the app that is using the library and how well it is isolated from the rest of the app.
I am building a new framework. The project is to be coded into Swift language, however the clients using this framework have the freedom of using either swift or Objective-C framework.
The question is how do I start. There could be numerous issues like
using structs in swift code but it cannot be made available in
objective C framework.
optionals are missing objective c
Even if I
write different set of files for Swift and Objective C, how will I
map them onto different frameworks under the same project.
Enums with other than Int as rawValue can't be used.
Tuples would not work
I know there have been a few questions around this but none have any satisfactory answer.
PS - Any link to a tutorial or blog would be super helpful too
I did this and got some unexpected results: I have trouble integrating the framework in Swift application. Objective-C works just fine.
You mentioned some of the caveats here.
I suggest doing this iteratively while writing test application in Objective-C which uses all the features. This way if there is some feature that does not cross Swift to Objective-C boundary well, it will be discovered as early as possible.
Your remarks about issues are generally correct with one small exception: optionals are not missing from Objective-C, they appear as nullable/nonnull modifiers on variables and method parameters. Although this does not replace optionals fully, it helps detecting issues early in the process.
Here is a random list of some other issues I discovered:
Bridging between Swift Error and NSError used in Objective-C. The conversion is not always as smooth at it could be, so better use NSError in exported code.
If you mix Objective-C and Swift in your framework, you cannot use bridging header, instead using modulemap files which tend to turn pretty large and complex.
Since you cannot embed frameworks inside a framework, you have to make sure that the application sets ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES flag for its target. This has to be clearly indicated in the documentation. Also, when creating fat library for your framework, you have to strip these files from the distributed SDK.
And, as I said in the beginning, I still have no success using the resulting mixed language framework in Swift application.
Hope, this will add to your list of things to take into account when developing the library.
Which language is preferable when developing with Typhoon framework, Swift or Objective-C?
I can't answer that question directly, however I can give you the information with which to come to your own decision:
Typhoon is a reflective, dynamic dependency injection container and takes advantage of the full Objective-C runtime. Pure Swift classes - ones that do not derive from NSObject - are Objective-C classes "under the hood" but have the following features:
The Objective-C runtime's reflection methods will not work.
They use C++ style inline, static or vtable dispatch which essentially prevents dynamic runtime augmentation of classes. Swift is a static language not just in regards to its time system, but also in this regard.
Answer:
You can use whichever language you prefer.
But if you're working in Swift you should be aware:
Classes being injected by Typhoon should derive from NSObject.
When it comes to Cocoa or Cocoa-touch you'll be working with UIViewControllers, UIViews and so forth, so we don't see this as a problem in the near future. However, eventually we'd like to provide an alternative version of Typhoon that works for "pure" Swift using clojures or perhaps compile-time instrumentation.
Xcode 7 contains an Objective-C variant, where you can define a type-hint for (homogenous) NSArray return values and properties, defined such as NSArray<UIImage*>.
I'd like to use this feature to rewrite my JSON-deserializer class (which needs such kind of type hints – previously I have solved this by adding a -(Class)jsonHintForKey:(NSString*)key to my classes that have homogenous arrays as properties.)
Do you know whether (and if so, how) I can use the Objective-C runtime to get the class of this new type hint at runtime?
The lightweight generics introduced in Xcode 7 are just compile time hints to help the compiler raise warnings, but at run time you get the same old behavior with your variable being just NSArrays of ids.
Source: WWDC '15 "Swift and Objective-C Interoperability" session
See the transcript of the talk:
So the entire lightweight generics feature is based on a type erasure model. Which means that the compiler has all of this rich static type information but it erases that information when generating code.
It is not possible to do that.
Generics were introduced in objective-c to improve the bridge between swift and objective-c. The advantage it gives to objective-c is only useful at compile time, and I that information is lost at runtime.