Contact Us

Use the form on the right to contact us.

You can edit the text in this area, and change where the contact form on the right submits to, by entering edit mode using the modes on the bottom right. 


Oak Ridge, TN, 37830
United States

Migrating code to Swift 3.0 XCode 8

Swift-Snips

Migrating code to Swift 3.0 XCode 8

Wade Cantley

I have a project that has a handful of dependencies on external frameworks to help make life somewhat easier.  However, when big point releases come up, everyone is doing the scramble to update their code.  That said, I probably should not have updated to XCode 8 and just waited for everyone to get on board and iron out the code differences... of which there are a LOT. 

So here are my fixes and their sources just in case you need further explanation as to why it works.  Chances are I won't fully understand all of the changes but first things first - get the code to build.


Cannot convert return expression of type 'Int32?' to return type 'Int?'

Bad :  return self.number?.int32Value

Good : return self.number?.intValue

Reason : Seems to be more generic in how it can return integers.


Inheritance from non-protocol type 'BooleaType' (aka 'Bool')

Bad : extension JSON: Swift.BooleanType {

Good : extension JSON: {

Reason : Admittedly, I am using this to modify SwiftyJSON which is a framework for processing JSON data. In doing some research it seems that they didn't allow BooleanType to allow for inheritance.  The suggested means of dealing with this is simply to remove the type.

References : 
https://forums.developer.apple.com/thread/53405


Type 'JSON' does not conform to protocol 'indexableBase'

Bad : extension JSON : Swift.Collection, Swift.Sequence, Swift.Indexable {

Good : Added to SwiftyJSON.swift line 222

public func index(after i: JSON.Index) -> JSON.Index {
return JSON.Index();
}

Reason : I think this was just a coding error as it would seem that you can't extend something that, as a function, doesn't exist.  So, if the return isn't an index, you can't extend it to be indexable. 

References
https://github.com/SwiftyJSON/SwiftyJSON/issues/542


Context member 'clear' has no associated value

Bad : self.tabBar.barTintColor = .clear()

Good : self.tabBar.barTintColor = UIColor.clear

Reason : Might want to be more explicit.

References : none


Empty collection literal requires an explicit type

Bad : var imageCache = []

Good : var imageCache: NSArray = []
or
var imageCache = [] as NSArray

Reason : Requires that variables be more explicit in how they are going to be used.

References : StackOverflow.com


Argument labels '(_:)' do not match any available overloads

Bad : formattedPriceValue = String(formatter.string(from: NSNumber(priceToNumber))!) 

Good : formattedPriceValue = String(formatter.string(from: NSNumber(value: priceToNumber))!)

Reason : Had to be explicit about about the value I was converting to NSNumber

References : Stackexchange.com


Value of type 'Error' has no member 'description'

Bad : self.locationStatus = error.description

Good : self.locationStatus = error.localizedDescription  as NSString

Reason : Seems to be a slight change in the naming conventions of the error member. I just removed "description" and waited for code hints to let me know what was available.  Since this new member is a "string" it needed to have the type converted to NSString.


Generic parameter 'ResultType' could not be inferred

Bad : let request = NSFetchRequest(entityName: entityName)

Good : let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)

Reason : Explicit typing of the result.

References : StackOverflow.com


Missing argument label 'checkType:' in call

Bad : siren.checkVersion(.immediately)

Good : siren.checkVersion(checkType: .immediately)

Reason : Requires a more explicit definition of passed parameters.

References : none


Cannot convert value of type 'NSMutableDictionary?' to type '[AnyHashable : Any]' in coercion]

Bad : tracker?.send(builder?.build() as [AnyHashable: Any])

Good : tracker?.send(builder?.build() as NSDictionary? as? [AnyHashable: Any] ?? [:])

Reason : ... evidently hashable dictionaries come back as AnyObjects which are now just "Any". This requires more research on my part but we are casting the result of NSDictionar as Any.

References
https://github.com/apple/swift-evolution/blob/master/proposals/0131-anyhashable.md


is ambiguous for type lookup in this context

Bad : let jsonDataSet: Array<JSON> =  jsonResult["data"].arrayValue

Good : let jsonDataSet: Array<SwiftyJSON.JSON> =  jsonResult["data"].arrayValue

Reason : Needs to be explicit about the framework that it is being called from.

References : StackExchange.com


Type 'Any' does not conform to protocol 'AnyObject'

Bad : for result:AnyObject in getResult! {

Good : for result:Any in getResult! {

Reason : AnyObject is being switched out for just "Any"

References : none


Cannot invoke initializer for type 'Int' with an argument list of type '(qos_class_t)'

Bad : return DispatchQueue.global(priority: Int(DispatchQoS.QoSClass.userInteractive.rawValue))

Good :  return DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated)

Reason :  the use of global(priority...) was deprecated, so used what seemed to be the next best replacement that would also allow for "userInitiated" or any of the other tested methods.

References : none


Left side of mutating operator isn't mutable: '..<' returns immutable value

Bad : for index in 0 ..< firstPage += 1 {

Good :  
let indexFirstPage = firstPage + 1
for indx in 0..<indexFirstPage {

Reason : Not sure... and it would seem that the spaces between the zero and the periods also throws an error. Not much luck in finding a specific example of why this is an issue.

References : none


C-style for statement has been removed in Swift 3

Bad :  for var index = firstPage; index <= lastPage; index += 1 {

Good : for index in firstPage...lastPage{

Reason : Phasing out the C-Style variable setting in the for loop.

References : StackOverflow.com


'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.

Bad

guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)) 
}) else {
return false
}

Good

guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}) else {
 return false
}

Reason : Increases safety when converting pointers between types.

References : StackExchange.com


Cannot call value of non-function type '((String) -> Any?)!'

Bad : if var _: AnyObject =  (getProperty[(indexPath as NSIndexPath).row] as AnyObject).value(forKey: "propertyId"){

Good : if var _: String =  (getProperty[indexPath.row] as! NSArray).value(forKey: "propertyId") as? String {

Reason :  The most I could figure here was that it didn't like me checking for just any object when the value for the picked key would ultimately be a string.  So being that the result is a string, I reformatted it to check for a string.   I am going to have to circle back on this to see if that is the correct way to approach this segment of code.

References : None


Cannot override 'locationManager' which has been marked unavailable: APIs deprecated as of iOS 7 and earlier are unavailable in Swift

Bad : func locationManager(_ manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {

Good : Removed, not being used.

Reason : On looking at my code, I wasn't really using that method for more than evaluating data that was sent within.  So I commented it out.  However I was using

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

I am not sure how one would find "old location" unless a person is just tracking the old location themself. 

References : none


Expression of type 'Any?' is unused

Bad : userPreferences?.updateValue("0", forKey:sender.restorationIdentifier!)

Good : _ = userPreferences?.updateValue("0", forKey:sender.restorationIdentifier!)

Reason : These methods do return something and Swift 3.0 wants them to be used in some way. So setting them to a placeholder variable satiates this this need.

References : StackExchange.com