27

I'm following a basic tutorial on building a simple iOS app in Swift.

It is written in Swift 2.x, and I work with XCode 8 Beta and Swift 3.

The tutorial suggests using NSFileManager to find a data directory. Class names have changed, so the auto-fixed Swift 3 looks like this:

static let DocumentsDirectory = FileManager().urlsForDirectory(.documentDirectory, inDomains:.userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.URLByAppendingPathComponent("meals")

However, Xcode now complains that

Value of type 'URL' has no member 'URLByAddingPathComponent'

I am unable to find out what the method is called now.

The NSURL Class Reference doesn't contain any hints as to how to address it from Swift 3

  • What is the new method name?

  • Where do I have to go to find a complete class reference for Swift 3 (or, the Swift 3 interface to the library the URL class is defined in - I still don't completely understand the nomenclature) so I can research these myself in the future?

Forge
  • 6,538
  • 6
  • 44
  • 64
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • 2
    Just .appendingPathComponent( – Leo Dabus Aug 07 '16 at 08:22
  • Take a look at the [new `NSURL` class reference](https://developer.apple.com/reference/foundation/nsurl) – it's now `appendingPathComponent(_:)` – Hamish Aug 07 '16 at 08:22
  • @Hamish argh, so I was looking at the wrong class reference. Thanks! I suppose I could delete this. (Edit: ah, there's an answer now. Do you want to post one yourself Hamish? Otherwise I'll edit the reference link into K.Nimo's answer.) – Pekka Aug 07 '16 at 08:24
  • 1
    You should update to beta 4 – Leo Dabus Aug 07 '16 at 08:27
  • 1
    Your code will change again after updating. You will need to use urls(for:in:) method for the documents directory and the appendingPathComponent won't throw anymore. Much cleaner – Leo Dabus Aug 07 '16 at 08:28
  • 2
    By the way, you may want to `FileManager.default` rather than `FileManager()`. – Rob Aug 07 '16 at 08:42
  • 2
    You can also cmd-click on `URL` in the Xcode editor, to jump to its definition. You should quickly find the methods which you need. – Martin R Aug 07 '16 at 08:54

3 Answers3

43

As of Xcode 8 beta 4, it is named appendingPathComponent(_:), and does not throw.

static let archiveURL = documentsDirectory.appendingPathComponent("meals")

Also as Leo Dabus points out in the comments, your documentsDirectory property will need changing to use urls(for:in:) in beta 4:

static let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

(Note that I've made your property names lowerCamelCase, as per the Swift API design guidelines. I would also recommend using FileManager.default, rather than creating a new instance.)

You can take a look at Apple's latest API reference guide to see the API naming changes that have taken place in Swift 3.

Community
  • 1
  • 1
Hamish
  • 78,605
  • 19
  • 187
  • 280
12

It has now changed to appendingPathComponent(_:) and it throws, so you need to wrap it in do - catch block

do {
  let archiveURL = try documentsDirectory?.appendingPathComponent("meals")
} catch {
  print(error)
}

Update

As per Xcode 8 beta 4, the appendingpathcomponent(_:) do not throw error.

For relevant info see answer by @Hamish

Community
  • 1
  • 1
Khundragpan
  • 1,952
  • 1
  • 14
  • 22
4
func appendingPathComponent(String)

=> Returns a new URL made by appending a path component to the original URL.

static let archiveURL = documentsDirectory?.appendingPathComponent("meals")

If it is directory:

func appendingPathComponent(String, isDirectory: Bool)

=> Returns a new URL made by appending a path component to the original URL, along with a trailing slash if the component is designated a directory.

static let archiveURL = documentsDirectory?.appendingPathComponent("meals", isDirectory: true)