9 ms·
Writing Apps in Go and Swift
- hellofunk 8y ago> Give Emporter a try and let me know how it compares to an Electron app. I don't see how this technique is comparable to Electron. The article does not describe anything related to a cross-platform user interface, which is what Electron addresses. You can write non-UI logic that is cross-platform in half a dozen mainstream languages and another dozen less popular ones. That's not a big deal. It's the UI component that is harder to achieve, and that is what Electron offers.
- sdinsn 8y agoYeah, I don't understand either. Is he referring to a different 'Electron'?
- youngdynasty 8y agoThanks for your feedback. Honestly, I was just being sassy. It probably is like comparing apples to oranges. This technique does not concern itself with a cross-platform interface. It only makes it possible to keep the logic cross-platform so that the "only" difference is the UI implementation, which can be done using native SDKs.
- iainmerrick 8y agoI still find it hard to write maintainable multi-threaded code for macOS or iOS [...] without having to worry about the minutiae of parallelism (threads, semaphores, locks, barriers, etc.). I find this surprising, as GCD does insulate you from that low-level stuff. When you need to work with mutable data, just create a dispatch queue, and only ever access the data by dispatching a function to the queue. Both Swift and Objective-C have friendly syntax for anonymous functions that makes this lightweight and easy.
- tannedNerd 8y agoThis reads like someone who purposely missed that part of the documentation just to write this article. I think I would have less hang ups if the author just came out and said I wanted to try using Go for multi-threaded code with Swift instead of trying to make GCD sound so confusing.
- sephoric 8y agoEven so, I'm glad it's been written. I didn't know you could call Go code from C code (new feature since Go 1.5 apparently) or that Swift could access compiled files with these "module map" things. I'm really glad to see they've both evolved to include useful interoperability and play nicely with other things now, and I'm glad this article shows how in a practical way.
- favorited 8y ago> Swift could access compiled files with these "module map" things That's been the case since it was released – all Swift C / ObjC interop happens at the "module" level. You write a Clang module map (if you're not using a system library which already has one), point the map at the relevant header(s), then you can import that module into your Swift code. That said, not everything is capable of being imported (variadics, complex macros, VLA structs, and a few others).
- mmjaa 8y agoIndeed .. things have come a long way since I tried to port IPFS to iOS .. https://github.com/seclorum/ios-go-ipfs https://github.com/seclorum/ios-go-ipfs It seems like there's a better way to go about this than my method. I was motivated to do this not because I don't like GCD (I still don't) but because I really like Go and IPFS and didn't think that iOS should be left out of the party. But, looking at it again, I still don't think GCD is all that great. This seems to have been intentionally designed to be different from the way so many other systems handle the issue - or at least, different enough that its still relatively discomfiting to attempt to port something away from iOS and not just to it ...
- tylerflick 8y ago
- tabs_masterrace 8y agoI found adopting a functional reactive programming really works well for multithreaded systems. GCD is super great and I use it a lot (...if you had to extend AsyncTask recently: my condolences), but it doesn't safeguard you from race conditions, dealing with locks and all that fun stuff.
- woolvalley 8y agoI don't have a lot of golang experience, but from what I can see here, golang doesn't really either: https://tour.golang.org/concurrency/1 https://tour.golang.org/concurrency/1 Channels seem like a simple thread safe stream for the most part, which you can get with Rx.
- Groxx 8y agoThis is correct, golang doesn't give you thread safety for free. Values passed via channels are safe as they're implicitly locked (i.e. it's a blocking threadsafe queue), and there are happens-before semantics for starting a goroutine, otherwise you're on your own (explicit locks / atomics / lock-wrappers like sync.WaitGroup). E.g. variable assignment isn't even atomic.
- pornel 8y agoGCD is fantastic and way better than everything on macOS before it, but it's still not a silver bullet (neither is Go). Cocoa is incredibly fragile about the main thread, so you need to be super careful what runs in what queue. If you add KVO/bindings into the mix, it needs an extraordinary level of paranoia^Wdilligence.
- saagarjha 8y ago> Cocoa is incredibly fragile about the main thread, so you need to be super careful what runs in what queue. This basically just boils down to "don't touch the UI off the main thread". There are some exceptions with CoreAnimation, but other than that the main thread checker will yell at you if you do something wrong.
- favorited 8y agoThe main thread checker is a godsend. Enabling it + TSAN + Core Data concurrency assertions have reduced the threading bugs my team deals with to almost 0. Anywhere we're doing something specific, we make liberal use of `dispatchPrecondition(condition: .onQueue(mySerialQueue))` or `assert(Thread.isMainThread)`. Even in places where we are doing multithreaded UI rendering (mostly CATiledLayer), it's become a non-issue. It's a night-and-day difference compared to 5+ years ago.
- Matthias247 8y ago> Cocoa is incredibly fragile about the main thread That basically applies to all UI framework. At least I'm not aware about one which provides good support for accessing it from another thread. There is obviously a reason for it, which is that UI frameworks are incredibly stateful, and trying to manipulate lots of state from multiple threads at once rarely works out well.
- pjmlp 8y agoI think BeOS tried to and it did not went well with common threading issues poping up on BeOS apps. Not sure if Haiku has any improvements regarding it.
- coldcode 8y agoI don't find GCD difficult to write for, maybe if you are used to Go it is different enough. Not sure what exactly you would use Go for in an iOS/Macos app unless maybe you have a Go framework you want to include.
- saagarjha 8y agoIsn’t this what the author is doing?
- mmjaa 8y agoI consider GCD to be a bit of a smell - not because its difficult to write for, but rather because its difficult to port such code elsewhere. And really, this seems to be the only rationale for Apple having maintained it as a component of the architecture for iOS - to be relatively different, or just different enough, from other systems to dissuade porting the code elsewhere.
- almostdigital 8y agohttps://github.com/apple/swift-corelibs-libdispatch https://github.com/apple/swift-corelibs-libdispatch
- armadsen 8y agoYeah. Worth noting too that libdispatch has been open source since it was released 10 years ago. I compiled and used it on Linux before Swift was out.
- mmjaa 8y agoSure. The solution to not wanting to be dependent on Apple's software is .. to use more of Apples software. Not really rational.
- iainmerrick 8y agoIt’s open source. You can use it on Linux rather than being tied to MacOS or iOS. What’s your objection?
- saagarjha 8y agoSwift Strings can transparently map to UnsafePointer<CChar> when necessary; is there a reason why this doesn’t work in this case?
- benatkin 8y agoHeads up: you made this error at least twice, once in the article and once in the repo. https://brians.wsu.edu/2016/05/31/complement-compliment/ https://brians.wsu.edu/2016/05/31/complement-compliment/ It's complementary instead of complimentary. The word "complimentary" is rarely used, but could be used if you were to mention books related to complimenting people.
- youngdynasty 8y agoThanks!
- tptacek 8y agoHow well does this work? Can you call a Go library function that spawns goroutines?
- youngdynasty 8y agoYes! I've shipped an app, on the Mac App Store, which uses Go in a non-trivial way (including spawning goroutines). The link is in the article.
- bsaul 8y agoZenly ( http://zen.ly http://zen.ly, millions of users, bought by snapchat ) has had an app coded in go and swift for ios ( and go and java for android) for a few years. Judging by the app, and the fact that it’s cross platform i’d say the go part does all the data processing part. https://m.youtube.com/watch?v=R0oaOohl5jk https://m.youtube.com/watch?v=R0oaOohl5jk ( in french but the slides are in english)
- sshb 8y agoGo has great crypto library, so I've wrapped it for use with Swift: https://github.com/lastochkanetwork/EasyPGP https://github.com/lastochkanetwork/EasyPGP
- gcbw2 8y agoI am go ahead and say it: Go is a replacement for Perl. It is nice for process and machine administration automation. Can you write your app in go? yes. Could you also write your app in perl cgi? sure. Did many people wrote perl cgi apps? yes. did they regret it. yes. Will people writing apps in go will regret it? who knows. Probably yes. This comment is not about the language per-se. it is about the current goals of the people with money and weight behind the language right now. I guess the regret will come or not if those goals keep or change.
- networkimprov 8y agoComparing Go with Perl is rather odd. Maybe you could tell us why we might regret it more than using Java or C# or Node.js?
- rantanplan 8y agoWas perl ever the language of choice for distributed services or database systems? Did I miss that part of history?
- axaxs 8y agoThey couldn't be further from each other. Just from browsing code, they are on opposite ends of the spectrum. Go is easily readable, but at the cost of brevity. Perl is -typically- unreadable, with a lot of one liner magic. If you are stating merely can a person write a web app in both, well, I think that goes for any language in existence.
- cr0sh 8y agoPerl could've been readable - nothing in the language prevents you from writing readable code. The problem was two-fold, imho: 1) regex was treated like the primary way to do things - even when it wasn't necessarily called for - at the expense of readability (and Perl supported it so well) 2) sysadmins The two combined together (and possibly the fact that it was the early days of commercial internet service) led to the idea that anything done in Perl was destined to look like "line noise" to actual SWEs. /just how I saw it...
- 8y ago
- bunnycorn 8y agoSomeone that doesn't know how to write Swift, tries to find faults at all costs. Go, horrible as it is, doesn't lack cultists.
- saagarjha 8y agoI don't see the author pointing out any faults in Swift. There's a passing comment about GCD being complicated, which I personally disagree with, but this isn't specific to Swift.
- axaxs 8y agoThanks for sharing this! As someone who writes in Go every day but stopped following it a while back, I had no idea you could even call Go from C much less Swift.
- alexashka 8y agoJust wanted to say that module maps are absolutely not necessary to have static libraries (.a file author compiles his go program to) in your project. All you need is an objective-c bridging header where you do an #import "name_of_header_.h" for every header. After that, the headers are visible to all of your swift code. It's no different than mixing objective-c and swift, except here you're mixing your language of choice, compiled to callable C functions inside a static library. To recap - drag .h and .a files the same way you have .swift files into your xcode project. Add a BridgingHeader.h file, go to it, fill it with #import "name_of_header.h" statements. Lastly, the project needs to know you're using a bridging header, that's done in the project target's Build Settings tab, under "Objective-C Bridging Header" you need to have the value set to the filename you chose for your bridging header. This is not unique to calling Go in Swift btw - any language that can be called from C, can be called from Objective-C, and therefore Swift. One thing to be aware of is memory management - unless you're passing things by value (copying), making sense of when things can be safely deallocated across languages is non-trivial.
- onderweg 8y agoI found your article particularly interesting, because lately I've been experimenting with calling Swift from Go. The approach is based on the same principle: cgo as bridge between Go and a C library. The C library is build by the Swift package manager. Blog post on Dev community with details: https://dev.to/gerwert/calling-swift-from-go-5dbk https://dev.to/gerwert/calling-swift-from-go-5dbk