What is the correct semantic versioning change to make when updating a podspec for a new Swift version?
For example, I am currently updating my project to Swift 5.1 (and therefore Xcode 11). The changes to the source code are only Swift 5.1 tweaks like implicit returns from single-expression functions. The underlying API, functionality and iOS deployment target is not changing at all.
Typically, I would increment the PATCH version by 1, but I've honestly never been sure because of how https://semver.org/ describes what to increment:
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards compatible manner, and
PATCH version when you make backwards compatible bug fixes.
I'm not making API changes, adding new functionality or fixing any bugs, but I still need to change the version in my podspec.
I think this is an objective question, but the community can feel free to vote it down if not ;P
Related
I know Swift is not yet ABI stable, but does that only count for major versions of Swift?
Is there any guarantee that minor or patch versions (under semantic versioning) of Swift are ABI stable?
I'm guessing there is no guarantee here, but just wanted to double check if anyone has come across anything detailing ABI stability for different minor/patch versions of Swift.
Also, if I use a Swift binary framework compiled with a different version of Swift I get a compiler error usually. If I don't get a compiler error in my project does that mean it is safe, or could there still potentially be runtime issues with a slightly different (patch version) of Swift?
Update 3
We also have module stability, starting with Xcode 11, with the help of the newly introduced .swiftinterface files. One caveat, though, is that the code will have to be build with the -enable-library-evolution flag. More details here.
Update 2 Module stability is scheduled for Swift 6: https://swift.org/blog/abi-stability-and-more/#module-stability
This is an excerpt from the Swift evolution repo.
Update Swift 5 comes with some ABI stability:
The Swift 5 release will provide ABI stability for the Swift Standard Library.
Unfortunately, not yet. For Swift 4, they state this here: https://swift.org/blog/swift-4-1-release-process/.
Swift 4.1 is not binary compatible with 4.0. It contains a variety of under-the-hood changes that are part of the effort to stabilize the Swift ABI in Swift 5.
Hopefully we'll get ABI stability in Swift 5
I think we should know what is ABI stability firstly, After that your confusion has already been removed.
Today, the latest version of Swift is 3.1, so chances are if you ship an app tomorrow, your app bundle will contain the Swift dynamic libraries for 3.1, however, there are plenty of apps in the store right now which link 3.0, 2.3, and probably even some older apps that link 2.1 and earlier. Nothing is stopping me from downloading your app (on 3.1) and my app (on 2.3) and running them side-by-side on my iPhone with iOS 10.3, since both apps link against their own bundled version of Swift. It's exactly the same as you bundling Alamofire 4.4 and while I bundle 3.0.
When a language is ABI-stable (Application Binary Interface), that means it is packaged and linked with the operating system itself, in this case: iOS. The Swift code you compile on your computer has a binary interface into the operating system itself rather than any dynamic library you bundle with your application. Because of this, Apple has to be able to guarantee that my Swift code, when compiled to machine code (bitcode, LLVM-IR, yada-yada), will be able to interface properly with the rest of the operating system, and (probably more importantly) will not break between versions of iOS / Swift.
As it stands today, the Swift language specification and compiler are not in a state where the Swift team would feel comfortable making this promise of ABI-stability; changes to Swift are still too frequent and the roadmap is still too long. As soon as the Swift library is merged into iOS, it becomes much much harder to make big changes.
Why does it matter?
Yes, the bundle size of your application will decrease because you will no longer have to include the Swift standard library in your Frameworks folder, which is nice.
Language changes will be smaller / less frequent, so you won't have to worry about events like migration from Swift 2 -> 3 (I'm still scarred from that)
Developers will be able to create 3rd-party libraries written in Swift and distribute pre-compiled frameworks (binaries), because they no longer need to bundle the Swift standard library into their framework, and will instead be linking against the same version of Swift as your app (the one packaged with iOS).
I have a project that was started using swift 2 in xcode 7. I am now using swift 2.3 in xcode 8. When I try to migrate to pro 3 I get several errors no project. Both from the libraries and from my code. First I update my pods and then do an automatic conversion of the project. My doubts are:
In case some library can give rise to error I can unlock it and convert?
Do I have to prepare something before starting the conversation? In the articles I read about it, I did not say anything else about it.
In case you continue using swift 2.3 will you have any future problems?
The application is very large, what would be the best option?
Honestly? Any project built with Swift since 2014 should be done with an understanding of code will break with every new version through Swift 3.X. (I'm not at all being critical, just practical.) This year, Swift 4.X is working hard to not break Swift 3.X code.
So with that starting point, here's my thoughts:
Take a backup of a working Swift 2.X app and archive it. Backup that backup.
Accept the price that should have been known when using any version before 3.X - the conversion will be painful and time-consuming.
Wherever possible, do not use third party add ins. They can add to the complexity of migrating to the latest version.
Do consider waiting for Swift 4. I'm not recommending this at all, but saying consider the big picture. But always remember eventually you will have to port things. (The good news is Swift 3 appears stable enough to say future upgrade will not be (at least) as painful.
Consider migrating everything at once. (If you have that golden backup duplicated in several places, that makes it easier.) Yes, there are ways to migrate individual project, files, etc. from 2.X to 3.X - and 4.X (along with what is likely Xcode 9) makes things easier going forward. But only if you are starting from 3.X.
Regards to Swift 2.3... the latest version of Xcode will not compile/build Swift 2.3. Take that as a sign - someday it will no longer be accepted in the App Store. That day may be 2-3 years away (or not), but It's almost 2 years since the promises of ABI and version compatibility were meant for Swift 3.0. BTW, only the latter happened.
EDIT: Regards to point #3 (avoid third party add ins where possible), I found two links expressing the issues that can come up:
Analyzing Third Party Libraries
Avoiding Third Party UI Libraries
I have a project which is almost completed in swift 2.2, Now I want to update the code to swift 2.2 to swift 3.0.I am using the Cocoapods for thrid party library integration and need following suggestions:
Should I go ahead update the libraries used first by running pod update? If any lib has not updated to support swift 3 what should i do?
Should I go ahead to update code to swift 3 manually or follow the XCode8 suggestions?
If I directly go for XCode8 suggestions then XCode8 starts giving suggestions to update library source code also.I am searching for the good way to handle all this. Thanks.
There is not a "best" way — as every project is potentially different in how easily it can be converted to an updated version of the language it's written in.
It would be recommended to:
Save a backup copy of the project before attempting to convert/migrate anything.
Follow the Xcode recommendations for updating the code.
Update the dependencies such as Cocoa Pods.
Fix any unresolved issues that might not have worked during the conversion.
Have patience, as often the conversion is not a one-click process.
If some of your libraries haven't been updated to Swift 3.0 then that's no problem, as you can tell the compiler to compiler only that library with the old compiler.
My suggestion, (and indeed how I updated my own projects), is to run the automatic migration wizard. (Editor>Code Syntax>Upgrade to latest Swift syntax). Then you should run pod update making sure to remove any version specifiers in your podfile.
Once you have done both of these things you can open your project and be greeted with a lot of compiler errors, the bigger your project the more you will have; unfortunately this is somewhat unavoidable because the built in migration tool sucks.
Now it is going to be a case of trudging through and fixing these errors, most of them will probably be something really simple like dropping AnyObject for Any, but a few may trip you up.
Now as I mentioned, if a library hasn't yet been updated for Swift 3.0 you can open your Pods project settings and select the library in question. Under build settings you'll find a key called Use legacy Swift syntax. Set this to true and rebuild. This forces the compiler to use the old compiler for this pod only.
I hope this in depth explanation is of help.
I Found some strategy migrating to Swift 3
I migrated directly to Swift 3.0. I use CocoaPods, so I migrated my dependencies first. This means following the steps above for each open source library (or private pod).
So far, the only dependencies I have for this project are my own libraries, which made this quite easy since I control all of the code. However, if you have third-party dependencies, then I would recommend opening an issue on the project to discuss migration plans with the current maintainers. I expect most popular projects are doing something similar to what I described above. For example, AlamoFire has a swift2.3 and swift3.0 branch. If needed, you can fork and migrate third-party libraries yourself — then submit a pull request or use your fork until the maintainers offer a solution. However, you should definitely reach out to project maintainers before submitting a pull request for migration.
Until Xcode 8 is final, you’ll need to point your pods to these new branches:
pod 'MyLibrary', :git => 'https://github.com/username/MyLibrary.git', :branch => 'swift3.0'
This tells CocoaPods to fetch the latest on the swift3.0 branch, instead of the latest published version.
Once your dependencies and Podfile are updated, you can run pod update to bring in the Swift 3.0 versions of each library. Then you can migrate your main app. I suggest commiting all of this migration in a single commit — update all dependencies, migrate your app, then commit — to keep your history clean.
Bugs
Xcode’s migration tool is not perfect.It would sometimes fail to migrate test targets, or only partially migrate app and framework targets. When this happens, you can attempt to run the tool again, but it’s probably best to make changes manually. Here are some of the specific issues that I saw:
Some expressions inside of XCTAssert*() did not migrate.
Some expressions inside closures did not migrate.
Sometimes waitForExpectations(timeout:) did not migrate.
Migrating NSIndexPath to IndexPath when used in certain contexts often resulted in derpy things like (indexPath as! NSIndexPath).section.
Enums with associated NSDate values migrated to case myCase(Foundation.Date) instead of case myCase(Date).
Sometimes optional protocol methods did not migrate, which can produce hard-to-find bugs.
Ref Links :
http://www.jessesquires.com/migrating-to-swift-3/
https://swift.org/migration-guide/
I am following this tutorial
The tutorial states to add libz.1.2.3.dylib. library, but because I have downloaded newer or older library (I don't know exactly if my library is newer or older that the library in the tutorial, but 99% it is newer). So, when I tried to add the libz.1.2.3.dylib. library, I didn't find it. However, when I typed libz I found these choices:
which one should I choose please?
In using dynamic libraries the one you normally use is libX.major_version.dylib in this case libz.1.2.dylib. This is a link to a library libX.major_version.minor_version.dylib which here is libz.1.2.5.dylib
The rationale for this is that the major version is changed only when the API is changed, the minor version is updated when any change is made. Thus your program should work when it uses any of the same major version and so you want the latest version.
In this case the tutorial had an older install and so its libz.1.2.dylib. should have pointed to libz.1.2.3.dylib.
For you you should use libz.1.2.5.dylib which should be like the tutorials version but with bug fixes and possibly extra functions that don't matter here as the tutorial won't call the new functions.
Normally libX.1.x.dylib would be older than libX.2.y.dylib but the writers might produce bug fixes to the old API whilst also working on the new API
Following on from the rational I gave libz.dylib should be a link to the highest number library but I would not use it as you are writing to a particular API so I would use a version specific (In this case if missing a link the I would not trust what libz.dylib points to)
I have made a project in xcode4.2 and when i opened it with xcode4.5 ,iOS 6 SDK it gives error 255 and the reason seems to be absence of libxml2.2.7.3.dylib.
What are my options is there any other substitute provided?
thanks
Xcode 4.5, or more precisely the iOS6 SDK (because the libraries available are dependent of the SDK, not the Xcode version) still has libxml2.2.dylib.
It is just probably not the version 2.2.7.3 but a newer, up-to-date 2.2.x.y version that is embedded in the SDK now.
You should generally not link your application with a specific version of libraries like that, but better with a generic version like libxml2.dylib or libxml2.2.dylib.
Generally libraries respect the semantic versionning, meaning that:
their major version change only when the API is not backward compatible with the previous major version,
the minor version change only when new methods are introduced in the API, but are still compatible with the previous API,
patch version means that some bug fixes have been made, but the API hasn't changed.
So if libxml respect this semantic versioning (and I guess is does, like quite every standard library), every version 2.2.x.y of libxml is API-compatible with any other 2.2.x.y version and will continue to work with your program. A hypothetic new version libxml2.2.x.z will simply fix bugs, but won't introduce any change in its API. And when a version of libxml2.3.x.y will arise, it will still be backward compatible with 2.1 and 2.2 too (just adding new features but not dropping the existing ones).
Thus, you can safely link your application with the generic library version libxml2.dylib, which will automatically point to the latest 2.x.y.z version available in the current SDK. Or link with libxml2.2.dylib which will point to the latest 2.2.x.y version (these are symbolic links to the latest versions, as all UNIX-like OSes use to do)
I think SDK for iOS6 just contains different version of libxml