Swift 2 Migration Problems

Swift 2 migration problems

Here's your updateAction() function with Swift 2.0's do/try/catch implementation:

func updateAction(){
var firstRandomNumber = Int(arc4random_uniform(5))
var firstCardString:String = String(self.cardNamesArray[firstRandomNumber])
var secondRandomNumber = Int(arc4random_uniform(5))
var secondCardString:String = String(self.cardNamesArray[secondRandomNumber])

self.firstCardImageView.image = UIImage(named: firstCardString)
self.secondCardImageView.image = UIImage(named: secondCardString)

let fileLocation = NSBundle.mainBundle().pathForResource("sound", ofType: ".mp3")

do {
player = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: fileLocation!))

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try AVAudioSession.sharedInstance().setActive(true)
}
catch {
print("Something bad happened. Try catching specific errors to narrow things down")
}

player.play()

let num = firstRandomNumber + secondRandomNumber + 2
self.label.text = "The sum is \(num)"
}

Swift 2.0 Migration errors

Cannot downcast from '[AnyObject]' to a more optional type '[NSManagedObject]'

In Swift 1.2, executeFetchRequest(:_) returned [AnyObject]?. In Swift 2, it returns [AnyObject] because the new try… syntax returns a non-optional.

(In the case that the method would return nil, the method would not return at all, and control would move to the catch block.)


'NSMutableDictionary' is not convertible to '[NSObject : AnyObject]'

This means you're trying to insert something into an NSMutableDictionary that can't be converted to an Objective-C object. In your case, I think it's because error is a struct conforming to ErrorType, rather than an NSError object. Try adding error1 instead.


Call can throw, but it is not marked with 'try' and the error is not handled.

save() might throw an error so it needs to be executed with try, instead of being evaluated as a bool. As Martin R. points out in the comments, the answer to this question provides a complete solution so I won't rehash it here.

Weird issue during migration from Swift 2 to Swift 3: Initializer has different argument names from those required by protocol

In Swift 2 we used to have NSData with the initializer init(bytes:length:). Since Apple has done a lot of renaming in Swift 3, NSData is called Data and the initializer is called init(bytes:count:) now.

So everything you need to do is to update your KeyType protocol:

public protocol KeyType {
init(bytes: UnsafeRawPointer, count: Int) // change "length" to "count"
func withSlice(_ f: (Slice) -> ())
func asData() -> Data
}

Error when migrating from Swift 1.2 to Swift 2

You see this error, because you're using dynamic frameworks, but they are not copied into your app bundle. On the simulator, the dynamic linker can still find the built framework in the build products directory. But this is not present in the sandbox of the device, where your app is executed.

It seems like that's the case because the build phase "Embed Pods Frameworks" is missing from your project. Please make sure that CocoaPods is up to date. (gem update cocoapods) You might then want to use your integration by pod deintegrate and re-install from scratch again. (Alternatively, you could remove the aggregate target Pods_*.framework from the linked libraries.) That should make sure, that all build phases are re-created by CocoaPods.

For references, you should have the build phases like seen below in your project's target:

build phases in Xcode

The mentioned aggregate target framework is seen in the "Link Binary With Libraries" pane as Pods.framework here. The name depends on whether or not you integrate multiple targets of your project and how they are named. So it could be also named Pods_YourApp.framework.

swift 2.3 to swift 3.0

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:

  1. Take a backup of a working Swift 2.X app and archive it. Backup that backup.
  2. Accept the price that should have been known when using any version before 3.X - the conversion will be painful and time-consuming.
  3. Wherever possible, do not use third party add ins. They can add to the complexity of migrating to the latest version.
  4. 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.
  5. 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.
  6. 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

core data migration issue: storePath cannot be initiated

If you removed if from if let , then you have to remove { } also , You can try

public func removeExistingModelStore() -> (success: Bool, error: Error?) {

if FileManager.default.fileExists(atPath: storeURL.path ) {

do {
try FileManager.default.removeItem(at: storeURL)
return (true, nil)
} catch {

return (false, error)
}

}

return (false, nil)
}

Unable to do a Realm migration in Swift

This exception will be thrown when stored data doesn’t match the model you have in code.

You shouldn’t need to do anything in the migration block, however you will need to trigger a migration by updating the value of Realm.Configuration.schemaVersion, e.g.:

schemaVersion: 3,


Related Topics



Leave a reply



Submit