Swift - how to use malloc? - ios

I'm trying to translate an Objective-C app into Swift and I don't know how to implement a malloc.
Is it possible to use it in Swift?
Thank you

You need to implement a bridging header when you use ObjC or C from Swift. The functions exported by your bridging header are then available in your Swift app/module. See here, for the overview.
If you just need to "call some code" on the C-side, then the functions exported from C are basically just wrappers for Swift. However, if you need to interact with the data returned from those functions -- especially if malloc'd and not a simple primitive -- Swift has a number of C related types ready for your use (see here for specifics).
Furthermore, if you're trying to wrap or interact with C++ code, you can't directly do so from Swift. You have to setup an initial interface with ObjC or C for the C++ code, and then bridge that to Swift. Not really fun at all, but thankfully it's not as common a use case as bridging ObjC (primarily) or C.
... and for what it's worth, unless you need low level Core Audio for some reason (granted, like porting an app you already have), AVAudioEngine (iOS8+) is so much simpler for any applicable use case than Core Audio, and is readily available in Swift.

Related

Spawn thread with Swift entry point from within C function in iOS

Is it possible to spawn a thread with a Swift entry point from within a C function in iOS? For example, using gcd or the POSIX threading API (not sure if this can be used within an iOS app or not) and specifying a function signature for a Swift function?
I am not trying to solve a specific problem here, but am curious about practical limitations of Swift & C interoperability within iOS. It seems that Apple provide seamless cross-compatibility bridging Swift to C, but I haven't found much about going the opposite direction.
You can access POSIX threading mechanisms in Swift. I have some examples of working with C in this project and this other hobby project. Hopefully they are useful to you.
When working with things like pthread_create you will want to pass in either a Swift function or closure as the function pointer argument. I attempted going from Swift => C and having C start the thread with a Swift function via #_cdecl and wasn't able to get it working. It might be possible but the context of how I had things setup I couldn't get it in this case.
The other thing to keep in mind is that once you are in C land you will need a way to get back. This is typically done through void* as your context pointer. From Swift you will likely want to pass in an UnsafePointer you are managing or use Unmanaged<T> to directly pass a class instance you have into C and back into Swift.

Replace old Objective-c library by new Swift one in several apps

I have an old library in objective C, developped by several people following (one stop and the next continue the project...).
This library is used in several applications, most of them developped in objective C.
I want to add new features in this app, but the code is not maintainable actually (no tests, no comment, etc...).
My main idea was to rebuild a framework or library in Swift. I have the business requirement but I'm not comfortable with objective c.
Am I going to have compatibility problems if I want to use my new swift library in "old" objective C application, or It could be great If I don't change the API?
Could it be transparent for the client who have his own application and have to use the new library now?
As long as you keep the interface the same and mark all previously public methods/properties as #objc, there should be no breaking changes to the API of the library and hence all consumers should be able to continue using it without any changes on their side.
However, be aware that having to mark all methods as #objc will limit your ability to use the full extent of Swift, since some features of Swift are not available in Obj-C and hence if you want your types/functions to be available in Obj-C, you cannot use such features (i.e. you cannot use tuples in function signatures or add methods to your enums).

Can I reference an Ada library in a Swift app?

I'm relatively new to Swift (I've tinkered with Python and HTML in the past)- but I'm currently working on an app with a group.
This app already exists as a desktop program written in Ada and we were hoping to port it over to Swift and put out an iPhone app.
My understanding is that I can (likely?) turn the Ada into C with a converter, then reference the C in Swift? Is this correct, or have I overlooked something due to not being familiar with the languages?
If correct, how would I go about actually executing this since I have little experience in Swift and C?
This is a pretty loaded question, so thank you for any help or insight!
edit: said desktop application is open source and available for all use- I do not intend on stealing anyone's work
I'm assuming that you can easily pull out the parts of the Ada program that you want to use in the iPhone program. If the code that you want to port over has other dependencies, then you have to make sure that you can get all of these dependencies for iOS as well. This may be extremely difficult for UI toolkits, if you use one.
To call foreign functions in Swift, you usually need to use a bridging header. Your target's bridging header contains C and Objective-C declarations of classes, functions and variables that Swift should be able to call into. As long as the language that you want to call into can export C-compatible bindings (which should be the case of Ada), then you will be able to call these bindings by declaring them in your bridging header.
If the part of the desktop Ada program that you want to use can easily be isolated in a library (static or dynamic), and you are capable of building that library as an ARM Mach-O library, then it's simply a matter of declaring the functions that you want to use from the library in your app's bridging header. You can refer to GNAT User's Guide for Native Platforms: Interfacing to C for the directives to use to expose an Ada function to C, and by exposing it to C, you're also exposing it to Swift. I'd try this first, as maintaining the almost-unmodified Ada source is almost certainly going to be easier than maintaining a mechanically-translated C version of the Ada source.
If that doesn't work, then yes, translating the Ada source to C code will also allow you to reference it from Swift. You will also have to ensure that the functions that you need to call are declared in your bridging header.
It looks like it used to be possible to compile Ada in Xcode when Xcode still supported the GCC compiler. That was removed a while ago.
If there are translators that will translate Ada to C then you could use C natively in an Objective-C iOS app. (Objective-C is a pure superset of C, meaning that all C code is also legal objective-C.)
Swift "plays nice" with C and Objective-C as long as you limit yourself to the types and classes that C and Objective-C understand, but inter-operating between Swift and C/Objective-C is somewhat tricky and tedious. You would have a fair amount of reading and study to do in order to learn how to build an app that uses both, on top of everything else you would need to learn.
Unless you're dealing with many thousands of lines of Ada code it might be better to find somebody who knows both Ada and Swift to translate the code for you, or for you to learn Swift and then translate it yourself.
Unfortunately, There is, at this time, no Ada compiler which targets iOS available to the public.
If you have cash to spend you could contact AdaCore for one, don’t expect it to be cheap though.
Believe me, there are some of us who would like to target iOS with Ada.
I am only aware of two Ada to C compilers, the most powerful one (AdaMagic) is now known as MapuSoft Ada-to-C/C++ changer. You'll need either Windows or Linux execution environment to run translator (Wine, Docker, etc. on macOS). Also, you'll need to limit yourself to Ada 95. AdaMagic is said to support a "subset of Ada 2005", but I am yet to stumble upon this subset. Also you'll need to port the runtime or a part of it. If you disable runtime checks, the amount of runtime required to port becomes lower, so it is up to you how much time you are willing to spend on it.
It has two modes of operation, either targeting C, or C++, I recommend C++ because throw-catch is a better match with modern Objective-C runtime (utilizing C++ ABI behind the scenes) than C setjmp/longjmp.
With some effort you'll get something up and running.
It is a pity Ada developers are so unaware of this option. Maybe somebody could find time to port AdaMagic to EmScripten, iOS, Elbrus or whatever essential target the humanity is missing to start mass Ada adoption.
Others advised producing Swift bindings from bridging headers, but IMO the winning strategy would be to write glue code in Objective-C++ hybrid. Objective-C++ will have access to both Swift code (viewed as external Objective-C classes) and Ada-to-C++ translated code. For instance, it will be able to catch C++ exceptions from Ada and throw Objective-C ones or vice versa.
Another compiler is GNAT CCG aka SPARK2C. It is designed to target embedded devices having no other Ada compiler. It supports recent Ada standards, but is very limited with regards to features requiring runtime. Basicly, there is no runtime. No runtime, no problem. Nothing to port. In this compiler one can return limited record from function (Ada 2005+ feature), but cannot have RAII, tasking, etc. I guess, that are far more strict requirements than Ada 95. GNAT CCG is not yet publicly available, but I expect it to appear before annual Make with Ada, otherwise that would be a very stupid situation.
Another options are Ada-to-Java or Ada-to-.NET, maybe they can work for your application better than others.

Making a Swift OSS library compatible with Objective-C

I am building a library in Swift, and it has to support Objective-C.
I already checked this answer which recommends to write the library in Objective-C but the requirements that were given to me are to write the library in Swift. I am delivering the library in source form, so the argument there (against writing the library in Swift) about unstable ABI should not apply in my case.
So I've heard that in order to make this Swift library work for Objective-C, I will have to avoid using the advanced features in Swift that are not available in Objective-C. Examples of these are:
Generics
Structs
All Swift classes must derive from NSObject
So my 2 questions are:
Where Can I find an exhaustive list for those constraints?
How can I quickly test that my library is compatible with Objective-C? I am not familiar at all in the interoperability topic of Swift and Objective-C. Not a lot articles that I could find online. Is the official Apple docs sufficient? and which parts can help?
I appreciate all the help here.
The most comprehensive list of Swift features not available from Objective-C is in the Swift Type Compatibility section of Apple's Using Swift with Cocoa and Objective-C guide.
Quoting from there, the list of exclusions are as follows:
Generics
Tuples
Enumerations defined in Swift without Int raw value
type
Structures defined in Swift
Top-level functions defined in Swift
Global variables defined in Swift
Typealiases defined in Swift
Swift-style variadics
Nested types
Curried functions
The whole guide is worth reading, but I'd pay particular attention to the Mix and Match section which describes calling Swift from Objective-C and vise-versa, including external frameworks.
I would definitely recommend doing as #Mike Taverne suggests: make a suite of unit tests in Objective-C which exercise the APIs you've developed in Swift. That's the best way to make sure it all works as expected.
There are more things good to know beforehand.
You cannot extend swift class by objective c class.
You cannot use #objc on generic swift class or method (you can use generics in #objc swift class on methods though)
So the api will be more limited than if written in objective c as it support generics (though people like to say not real generics etc...) and not to be able to extend any class you provide in your api can be quite limitation too, but still it's doable.
You just have to put #objc everywhere and compiler will say you very quickly what is not supported. Also casting can be quite tricky sometimes... I ended up to cast like this because I was reciving objective c generic class from swift in swift code
as! CSResponse<AnyObject> as! (CSResponse<AnyObject> & CSListData)
This is working code, but direct cast is imposible.
Best is to write pure swift for swift and use objective c libs as needed otherwise you will and up fighting to write one line of code. (like me :))

How to deal with the lack of reflection in Swift?

As an experienced Objective-C developer who is now learning Swift , I'm really missing some of the reflection and dynamic features of Objective-C.
For eg: I had written a JSON serializer which automatically mapped keys and values using KVO and Objective C introspection , and there are open source libraries like Mantle which do this.
I could declare my object as an NSObject subclass and proceed but I feel that this is not the Swift way of doing things.
Is there any other way to accomplish the same tasks , while avoiding boilerplate , using what Swift provides ?
EDIT: (2016) this answer is auto-dated. Some of the advice may still be relevant but now that Swift is open-source, I would look into other possible answers.
There is no native KVO reflection like what you described built into Swift. See:
https://stackoverflow.com/a/24092370/798682
And based on what we do know about how the Swift compiler optimizes method execution at compile time (vs the pure runtime implementation of ObjC) it doesn’t seem likely to be added anytime soon. See https://stackoverflow.com/a/25438299/798682 and
http://blog.untitledkingdom.co.uk/obj-c-vs-swift/
for more info on that.
With all that being said, here is a blog post on some KVO alternatives in Swift:
http://blog.scottlogic.com/2015/02/11/swift-kvo-alternatives.html
and another that details some of the reflection capabilities that are in Swift:
http://freecake.angelodipaolo.org/simple-reflection-in-swift/.

Resources