Skip to content

Instantly share code, notes, and snippets.

@aldeed
Last active February 13, 2020 10:06
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save aldeed/05d7f6f5d7de3b41a400ae2254266634 to your computer and use it in GitHub Desktop.
Fix iOS Project Swift Errors

Fix iOS Project Swift Errors

In order to build the iOS app in the latest XCode, you need to convert the project to Swift 3.0. After you do this, when you try to run or archive the project, you will get a bunch of errors. This section explains how to fix them.

IMPORTANT NOTE: Fix all the RED errors. There will also be yellow triangles and the option to "update to recommended settings". Do NOT fix these things and do NOT update to recommended settings.

Info from Apple on what has changed in Swift: http://adcdownload.apple.com/Developer_Tools/Xcode_8_beta_6/Release_Notes_for_Xcode_8_beta_6.pdf ("New in Xcode 8 beta 6 - Swift Compiler" section on page 8)

"NSURL" is not implicitly convertible to "URL"

Click the error in the left pane, and then double-click on the Fix-It line in the popup. This will convert foo as NSURL to (foo as NSURL) as URL. This is because in Swift 3.0 most APIs have been converted to deal in URL class instead of NSURL.

"NSData" is not implicitly convertible to "Data"

Click the error in the left pane, and then double-click on the Fix-It line in the popup. This will convert foo as NSData to (foo as NSData) as Data. This is because in Swift 3.0 most APIs have been converted to deal in Data class instead of NSData.

localServerPort = port.uintValue

This error occurs in one place. Change this line:

localServerPort = port.uintValue

To this:

localServerPort = UInt(port)

"init" has been renamed to "init(describing:)"

This error occurs in two places.

Change this line:

let errorMessage = String(error)

To this:

let errorMessage = String(describing: error)

Change this line:

URLPath = String(asset.URLPath.utf16.dropFirst())

To this:

URLPath = String(describing: asset.URLPath.utf16.dropFirst())

Value of optional type "String?" not unwrapped

Click the error in the left pane, and then double-click on the Fix-It line in the popup.

Cannot force unwrap value of non-optional type "String"

Click the error in the left pane, and then double-click on the Fix-It line in the popup.

Value of type "Any" has no member "contains"

Click the error in the left pane, and then double-click on the Fix-It line in the popup.

Value of optional type "GCDWebServerRequest?" not unwrapped

Click the error in the left pane, and then double-click on the Fix-It line in the popup.

Value of optional type "GCDWebServerFileResponse?" not unwrapped

Click the error in the left pane, and then double-click on the Fix-It line in the popup.

Initializer for conditional binding must have Optional type, not "String"

This error occurs in one place. Change this line:

guard let version = itemURL.lastPathComponent else { continue }

To this:

let version = itemURL.lastPathComponent

Initializer for conditional binding must have Optional type, not "() -> URL"

This error occurs in one place. Change this line:

if let containingDirectoryURL = asset.fileURL.deletingLastPathComponent {

To this:

let containingDirectoryURL = asset.fileURL.deletingLastPathComponent

And then remove the ending } (the one after the ending catch one).

Also, deletingLastPathComponent is now a method, so within the do block, change at: containingDirectoryURL to at: containingDirectoryURL()

Cannot assign to property: "URLComponents" is a "let" constant

Two nearby lines have this error. To fix them, you don't edit those lines but rather change the line above them where URLComponents is defined.

Change this:

guard let URLComponents = URLComponents(string: URLPath) else {

To this:

guard var URLComponents = URLComponents(string: URLPath) else {

(change let to var)

Value of type "Error" has no member "userInfo"

This error occurs in one place. Change this line:

if let resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData] as? Data {

To this:

if let resumeData = (error as NSError).userInfo[NSURLSessionDownloadTaskResumeData] as? Data {

Specifically, change error to (error as NSError)

getResourceValue(_:forKey:) is unavailable

This is the most complex fix. Delete the entire extension URL block and replace it with this one:

extension URL {
  var isDirectory: Bool? {
    let values = try! self.resourceValues(forKeys: [.isDirectoryKey])
    return values.isDirectory
  }


  var isRegularFile: Bool? {
    let values = try! self.resourceValues(forKeys: [.isRegularFileKey])
    return values.isRegularFile
  }
}

Expression resolves to an unused function

You need to change two lines.

Change this line:

} as! () -> Void as! () -> Void as! () -> Void as! () -> Void as! () -> Void as! () -> Void as! () -> Void

To this:

}

And at the beginning of that block, change this line:

try dispatch_sync(queue) {

To this:

try queue.sync {
@v3rron
Copy link

v3rron commented Sep 18, 2016

This gist saved my day... Many thanks @aldeed

@harryward
Copy link

It also saved my day, what a pain!

@flashfabrixx
Copy link

Perfect! Thanks @aldeed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment