Objective-C
iOS Development
stringByAppendingPathComponent
Apple Documentation
Deprecated Methods

stringByAppendingPathComponent is unavailable

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

The error "stringByAppendingPathComponent is unavailable" occurs in Swift when you call this NSString method on a Swift String. Apple removed stringByAppendingPathComponent from the Swift String API because path manipulation belongs to URL and file-system APIs, not string manipulation. The replacement is URL.appendingPathComponent() or NSString.appendingPathComponent (via bridging). This article covers the migration path and modern alternatives.

The Error

swift
1let base = "/Users/alice/Documents"
2let full = base.stringByAppendingPathComponent("report.pdf")
3// Error: 'stringByAppendingPathComponent' is unavailable:
4// Use appendingPathComponent on URL instead.

This was removed in Swift 2 (Xcode 7). The method still exists on NSString in Objective-C, but Swift String no longer exposes it.

swift
1let baseURL = URL(fileURLWithPath: "/Users/alice/Documents")
2let fullURL = baseURL.appendingPathComponent("report.pdf")
3print(fullURL.path)
4// /Users/alice/Documents/report.pdf

URL.appendingPathComponent() handles path separators correctly:

swift
1let base = URL(fileURLWithPath: "/Users/alice/Documents/")
2let full = base.appendingPathComponent("report.pdf")
3print(full.path)
4// /Users/alice/Documents/report.pdf  (no double slash)
5
6// With subdirectory
7let nested = base
8    .appendingPathComponent("reports")
9    .appendingPathComponent("2024")
10    .appendingPathComponent("annual.pdf")
11print(nested.path)
12// /Users/alice/Documents/reports/2024/annual.pdf

Fix 2: NSString Bridging

Cast the Swift String to NSString to access the old method:

swift
1let base = "/Users/alice/Documents"
2let full = (base as NSString).appendingPathComponent("report.pdf")
3print(full)
4// /Users/alice/Documents/report.pdf

This works but is discouraged — Apple wants you to use URL for path manipulation.

swift
1let base = "/Users/alice/Documents"
2let file = "report.pdf"
3
4// Manual concatenation — fragile
5let full = base + "/" + file
6// /Users/alice/Documents/report.pdf
7
8// Problem: double slashes if base has trailing /
9let base2 = "/Users/alice/Documents/"
10let full2 = base2 + "/" + file
11// /Users/alice/Documents//report.pdf  (broken)

String concatenation does not handle edge cases. Always use URL or NSString bridging.

Common Path Operations with URL

swift
1let fileURL = URL(fileURLWithPath: "/Users/alice/Documents/report.pdf")
2
3// Get components
4print(fileURL.lastPathComponent)          // report.pdf
5print(fileURL.pathExtension)              // pdf
6print(fileURL.deletingLastPathComponent().path)  // /Users/alice/Documents
7print(fileURL.deletingPathExtension().path)      // /Users/alice/Documents/report
8
9// Change extension
10let docURL = fileURL.deletingPathExtension().appendingPathExtension("docx")
11print(docURL.path)
12// /Users/alice/Documents/report.docx
13
14// Check if directory
15var isDir: ObjCBool = false
16FileManager.default.fileExists(atPath: fileURL.path, isDirectory: &isDir)
17print(isDir.boolValue)  // false

FileManager Path Operations

swift
1let fm = FileManager.default
2
3// Documents directory
4let docs = fm.urls(for: .documentDirectory, in: .userDomainMask).first!
5let fileURL = docs.appendingPathComponent("data.json")
6print(fileURL.path)
7
8// Temporary directory
9let temp = fm.temporaryDirectory.appendingPathComponent("cache.tmp")
10
11// Application Support
12let appSupport = fm.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
13let configURL = appSupport
14    .appendingPathComponent("MyApp")
15    .appendingPathComponent("config.plist")
16
17// Create intermediate directories
18try fm.createDirectory(at: configURL.deletingLastPathComponent(),
19                       withIntermediateDirectories: true)

Migration Table

Old (NSString)New (URL / Swift)
stringByAppendingPathComponent:url.appendingPathComponent()
stringByDeletingLastPathComponenturl.deletingLastPathComponent()
stringByAppendingPathExtension:url.appendingPathExtension()
stringByDeletingPathExtensionurl.deletingPathExtension()
lastPathComponenturl.lastPathComponent
pathExtensionurl.pathExtension
pathComponentsurl.pathComponents
stringByExpandingTildeInPathNSString(string: path).expandingTildeInPath

Objective-C: Still Works

In Objective-C, stringByAppendingPathComponent: is still available:

objc
NSString *base = @"/Users/alice/Documents";
NSString *full = [base stringByAppendingPathComponent:@"report.pdf"];
// /Users/alice/Documents/report.pdf

The method was never removed from NSString — it was only removed from the Swift String overlay.

String Extension for Convenience

If you have a large codebase and need a quick migration path:

swift
1extension String {
2    func appendingPathComponent(_ component: String) -> String {
3        return (self as NSString).appendingPathComponent(component)
4    }
5
6    var lastPathComponent: String {
7        return (self as NSString).lastPathComponent
8    }
9
10    var deletingLastPathComponent: String {
11        return (self as NSString).deletingLastPathComponent
12    }
13
14    var pathExtension: String {
15        return (self as NSString).pathExtension
16    }
17}
18
19// Usage
20let path = "/Users/alice".appendingPathComponent("file.txt")

This bridges to NSString internally. Prefer URL for new code but this eases migration.

Common Pitfalls

  • Using string concatenation for paths: base + "/" + file does not handle trailing slashes, empty components, or special characters. Always use URL.appendingPathComponent() which normalizes the path.
  • Confusing file URLs and path strings: URL(fileURLWithPath:) creates a file:// URL. URL(string:) creates a generic URL. Use fileURLWithPath for local file paths and .path to convert back to a string.
  • Assuming URL.path and the original string are identical: URL(fileURLWithPath: "/tmp/") produces a path of /tmp (trailing slash removed). If you need the exact original string, keep it separately.
  • Not handling spaces and special characters: Path strings with spaces work with URL(fileURLWithPath:) but fail with URL(string:) (which expects percent-encoding). Always use fileURLWithPath for filesystem paths.
  • Using NSString bridging in new Swift code: While (path as NSString).appendingPathComponent() works, it bypasses Swift's type safety and URL-based design. Use URL for new code to benefit from the full API (exists checks, resource values, security-scoped access).

Summary

  • stringByAppendingPathComponent was removed from Swift's String — use URL.appendingPathComponent() instead
  • Create URLs with URL(fileURLWithPath:) for local paths and use .path to get the string back
  • For quick migration, cast to NSString: (path as NSString).appendingPathComponent(component)
  • All NSString path methods have URL equivalents — prefer the URL versions in new code
  • The method still works in Objective-C and via NSString bridging in Swift
  • Use FileManager.default.urls(for:in:) for standard directories (Documents, Application Support, Caches)

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.