Swift-foundation now available

CoreFoundation is actually still built for swift-corelibs-foundation. The major change from the previous release of Swift is that now swift-corelibs-foundation's role is that it is a compatibility library. It is built on top of the shared swift-foundation library. Its purpose is to provide as faithful of a reproduction of non-portable Objective-C code in Darwin's Foundation.framework as it can. The C code in CoreFoundation is a part of that. We hope that it becomes less critical over time as we rewrite things in Swift.

There is a new diagram in the README which might help explain the relationship between the projects more clearly.

@MahdiBM the main change for you as a server side Swift developer is that the code in swift-foundation is shared for all platforms, including Darwin. That means that it is better tested, more reliable, and more consistent with changes made to Darwin. We also now have a process for API proposals in open source to add functionality to swift-foundation for all platforms, and we have run 9 of those over the past year or so. In summary, server side Swift developers get a major update to the implementation of Foundation with Swift 6.

There is some Swift code in Foundation.framework that is not part of swift-foundation, but it is a fairly small amount, and shrinking over time. The majority of it is specialized for interop with Objective-C code and not that relevant to swift-foundation. As we move things over, however, we're including even that kind of code in open source so that swift-foundation contributors can see the whole picture. Additionally there are a few Swift types which just haven't ported yet but intend to keep working on. CharacterSet is a good example of that. A final category of code is Objective-C which makes little sense to port to Swift, either because it already has a Swift replacement (collection types are a good example), or because it is so Darwin-specific that bringing it to other platforms is not useful.

15 Likes

As for CoreFoundation, some functions such as CFStringConvertNSStringEncodingToEncoding and CFStringConvertEncodingToIANACharSetName that are currently available on both of Darwin and non-Darwin with import CoreFoundation are not exposed via Swift API.
FoundationEssentials uses them internally, but doesnā€™t seem to expose them publicly.
Will they keep available, or be rewritten in Swift?

CoreFoundation was never meant to be user visible with swift-corelibs-foundation. This is one of the big differences between Windows and Linux with swift-corelibs-foundation. Because the Windows port happened later, that was addressed and is why the CoreFoundation functions are not visible on Windows. I expect that as swift-corelibs-foundation becomes more a forwarder for swift-foundation, those APIs should shrink and disappear on Linux as well.

1 Like

All this talk about CoreFoundation is making me wonder how it will fit into the new arrangement on Darwin. Will it also be wrapping swift-foundation, will it continue being its own thing, or will it just take advantage of the toll-free bridge to use the ObjC version's wrapping of swift-foundation?

I can understand what you say, but Iā€™d rather insist that I donā€™t think CoreFoundation is a mere backend of swift-corelibs-foundation de facto.
For example, CFStringConvertEncodingToIANACharSetName and its complementary function CFStringConvertIANACharSetNameToEncoding (of which I gave examples above) are very useful to (and widely used by) server-side programs and web client programs.
I hope equivalent APIs are worked out in swift-foundation even if CoreFoundation would become unavailable.

2 Likes

Hey @YOCKOW - you're right that function doesn't seem to have a Swift equivalent in our current APIs. For functions in CoreFoundation that are useful in the Swift ecosystem, I think the best approach (as you mentioned) is to publish them as official Swift APIs rather than continue to call to CoreFoundation to use them (that way eventually they can be removed from CoreFoundation in swift-corelibs-foundation). This one in particular seems relatively simple in implementation and is actually already partially implemented (but not public) in swift-foundation since we use it when writing strings to files. I think this would be a great opportunity for a pitch for new API for FoundationEssentials. We actively review and bring in new APIs to Foundation - you can see some of the other pitches posted to this category for inspiration. I'm happy to help with the process if you or any others would like to start up a pitch thread for it! I think this could fit very nicely as new API for String.Encoding.

4 Likes

Yes, CoreFoundation on Darwin is a wrapper for swift-foundation.

For example, here is the entire implementation for CFCalendarCreateWithIdentifier:

CFCalendarRef CFCalendarCreateWithIdentifier(CFAllocatorRef allocator, CFStringRef identifier) {
    return (CFCalendarRef)[NSCalendar _newCalendarWithIdentifier:identifier];
}

Which is a direct call into this Swift code.

6 Likes

That makes sense since Foundation is now more open than ever.
I'd try to write a pitch if I have enough time, or I welcome someone else writing the pitch.
Thank you.

1 Like

As someone who has primarily created things for iOS, Iā€™ve been researching how to build a server to handle push notifications. Iā€™ve investigated AsyncHTTPClient and APNSClient as both work on Linux and use SwiftNIO (which I hear is great).

However, learning a whole new API and things like EventLoopFuture scares me a bit. In addition, much of the literature that would help me understand NIO based APIs employ Vapor to ā€œuncomplicateā€ things. I would like to avoid involving Vapor if possible.

Please forgive the long preamble (and possible dumb question), is it possible to use URLSession on Linux now? Would an NIO backed solution still be the better way to go about it?

There's no need to know anything about EventLoopFuture or NIO to use most if not all AsyncHTTPClient features. It has a high-level async API, and IIUC EventLoopFuture-based API is there for backward compatibility or for those who want absolute control over how their workload is scheduled.

Vast majority of the time you only need NIO if you write your own implementation of networking protocols or low level asynchronous I/O code. If you just need an HTTP server, Vapor, Hummingbird, or any other high-level library that hides NIO under the hood as an implementation detail is the way to go. NIO is not a high level library for end users, its primary audience is networking and I/O library authors.

The only API I reach for in NIO directly in my high-level code is the new _NIOFileSystem module, and sometimes ByteBuffer with its low-level binary decoding/encoding helpers when I need to deal with binary formats. But both of those are quite decoupled from low-level NIO parts like EventLoopFuture that you mentioned.

You can and could use URLSession on Linux during all this time. One major consideration (other than some API inconsistencies that are probably resolved by this point) is that FoundationNetworking has a dependency on libcurl and system cryptography libraries, most of those are linked dynamically. If you want all your networking code linked statically, AsyncHTTPClient may be a better solution in your case.

Another thing to note is that URLSession is available on Windows, while AsyncHTTPClient (and SwiftNIO in general) is not.

Thank you for the detailed reply, it clarifies some things but I donā€™t think this is completely accurate:

Foundationā€™s historic lack of full support for URLSession on Linux meant that NIO became the default path for networking on Linux, either through abstractions or directly. Bootstrapping, upgrading connections, handling frames, web sockets (forgot to mention I need ws support), and even more high level things like AsyncHTTPClient all use NIO at some level.

Before this release, learning/using some level of NIO was a required part of server development unless one wanted to use libcurl directly. There wasnā€™t a unified API that worked on all platforms, thatā€™s why this announcement has me so excited.

However, it sounds like full and cross platform support for URLSession has finally come to Linux. I that true?

If so, can I avoid NIO entirely and use what Iā€™m more experienced with? I hope thatā€™s a better phrasing of my situation.

NIO is primarily used for receiving network traffic, which is something URLSession cannot do. It all really depends on what you mean by 'server development'.

If you want to write something using URLSession that works currently on macOS, then Swift 6 will contain an implementation of FoundationNetworking that matches those on Apple platforms. If you want to be able to receive requests and handle inbound network traffic you'll need to reach for NIO or one of the frameworks

Ahh, thanks for the clarifications, I think my questions crossed the streams a bit.

URLSession now works on all platforms as it would on macOS and iOS. And separately, the functionality I would be needing in server applications is not provided by URLSession (regardless or platform or release), rather that is provided by NIO. Thanks all!

Will the Static Linux SDK also use this?

I believe getting that working is one of the main issues holding up a new snapshot build of the static linux SDK.

1 Like