forked from swiftlang/swift-corelibs-foundation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBundle.swift
327 lines (256 loc) · 12.7 KB
/
Bundle.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
import CoreFoundation
open class Bundle: NSObject {
private var _bundle : CFBundle!
private static var _mainBundle : Bundle = {
return Bundle(cfBundle: CFBundleGetMainBundle())
}()
open class var main: Bundle {
get {
return _mainBundle
}
}
open class var allBundles: [Bundle] {
NSUnimplemented()
}
internal init(cfBundle: CFBundle) {
super.init()
_bundle = cfBundle
}
public init?(path: String) {
super.init()
// TODO: We do not yet resolve symlinks, but we must for compatibility
// let resolvedPath = path._nsObject.stringByResolvingSymlinksInPath
let resolvedPath = path
guard resolvedPath.length > 0 else {
return nil
}
let url = URL(fileURLWithPath: resolvedPath)
_bundle = CFBundleCreate(kCFAllocatorSystemDefault, unsafeBitCast(url, to: CFURL.self))
if (_bundle == nil) {
return nil
}
}
public convenience init?(url: URL) {
self.init(path: url.path)
}
public init(for aClass: AnyClass) {
NSUnimplemented()
}
public init?(identifier: String) {
super.init()
guard let result = CFBundleGetBundleWithIdentifier(identifier._cfObject) else {
return nil
}
_bundle = result
}
override open var description: String {
return "\(String(describing: Bundle.self)) <\(bundleURL.path)> (\(isLoaded ? "loaded" : "not yet loaded"))"
}
/* Methods for loading and unloading bundles. */
open func load() -> Bool {
return CFBundleLoadExecutable(_bundle)
}
open var isLoaded: Bool {
return CFBundleIsExecutableLoaded(_bundle)
}
@available(*,deprecated,message:"Not available on non-Darwin platforms")
open func unload() -> Bool { NSUnsupported() }
open func preflight() throws {
var unmanagedError:Unmanaged<CFError>? = nil
try withUnsafeMutablePointer(to: &unmanagedError) { (unmanagedCFError: UnsafeMutablePointer<Unmanaged<CFError>?>) in
CFBundlePreflightExecutable(_bundle, unmanagedCFError)
if let error = unmanagedCFError.pointee {
throw error.takeRetainedValue()._nsObject
}
}
}
open func loadAndReturnError() throws {
var unmanagedError:Unmanaged<CFError>? = nil
try withUnsafeMutablePointer(to: &unmanagedError) { (unmanagedCFError: UnsafeMutablePointer<Unmanaged<CFError>?>) in
CFBundleLoadExecutableAndReturnError(_bundle, unmanagedCFError)
if let error = unmanagedCFError.pointee {
let retainedValue = error.takeRetainedValue()
throw retainedValue._nsObject
}
}
}
/* Methods for locating various components of a bundle. */
open var bundleURL: URL {
return CFBundleCopyBundleURL(_bundle)._swiftObject
}
open var resourceURL: URL? {
return CFBundleCopyResourcesDirectoryURL(_bundle)?._swiftObject
}
open var executableURL: URL? {
return CFBundleCopyExecutableURL(_bundle)?._swiftObject
}
open func url(forAuxiliaryExecutable executableName: String) -> URL? {
return CFBundleCopyAuxiliaryExecutableURL(_bundle, executableName._cfObject)?._swiftObject
}
open var privateFrameworksURL: URL? {
return CFBundleCopyPrivateFrameworksURL(_bundle)?._swiftObject
}
open var sharedFrameworksURL: URL? {
return CFBundleCopySharedFrameworksURL(_bundle)?._swiftObject
}
open var sharedSupportURL: URL? {
return CFBundleCopySharedSupportURL(_bundle)?._swiftObject
}
open var builtInPlugInsURL: URL? {
return CFBundleCopyBuiltInPlugInsURL(_bundle)?._swiftObject
}
open var appStoreReceiptURL: URL? {
// Always nil on this platform
return nil
}
open var bundlePath: String {
return bundleURL.path
}
open var resourcePath: String? {
return resourceURL?.path
}
open var executablePath: String? {
return executableURL?.path
}
open func path(forAuxiliaryExecutable executableName: String) -> String? {
return url(forAuxiliaryExecutable: executableName)?.path
}
open var privateFrameworksPath: String? {
return privateFrameworksURL?.path
}
open var sharedFrameworksPath: String? {
return sharedFrameworksURL?.path
}
open var sharedSupportPath: String? {
return sharedSupportURL?.path
}
open var builtInPlugInsPath: String? {
return builtInPlugInsURL?.path
}
// -----------------------------------------------------------------------------------
// MARK: - URL Resource Lookup - Class
open class func url(forResource name: String?, withExtension ext: String?, subdirectory subpath: String?, in bundleURL: URL) -> URL? {
// If both name and ext are nil/zero-length, return nil
if (name == nil || name!.isEmpty) && (ext == nil || ext!.isEmpty) {
return nil
}
return CFBundleCopyResourceURLInDirectory(bundleURL._cfObject, name?._cfObject, ext?._cfObject, subpath?._cfObject)._swiftObject
}
open class func urls(forResourcesWithExtension ext: String?, subdirectory subpath: String?, in bundleURL: NSURL) -> [NSURL]? {
return CFBundleCopyResourceURLsOfTypeInDirectory(bundleURL._cfObject, ext?._cfObject, subpath?._cfObject)?._unsafeTypedBridge()
}
// -----------------------------------------------------------------------------------
// MARK: - URL Resource Lookup - Instance
open func url(forResource name: String?, withExtension ext: String?) -> URL? {
return self.url(forResource: name, withExtension: ext, subdirectory: nil)
}
open func url(forResource name: String?, withExtension ext: String?, subdirectory subpath: String?) -> URL? {
// If both name and ext are nil/zero-length, return nil
if (name == nil || name!.isEmpty) && (ext == nil || ext!.isEmpty) {
return nil
}
return CFBundleCopyResourceURL(_bundle, name?._cfObject, ext?._cfObject, subpath?._cfObject)?._swiftObject
}
open func url(forResource name: String?, withExtension ext: String?, subdirectory subpath: String?, localization localizationName: String?) -> URL? {
// If both name and ext are nil/zero-length, return nil
if (name == nil || name!.isEmpty) && (ext == nil || ext!.isEmpty) {
return nil
}
return CFBundleCopyResourceURLForLocalization(_bundle, name?._cfObject, ext?._cfObject, subpath?._cfObject, localizationName?._cfObject)?._swiftObject
}
open func urls(forResourcesWithExtension ext: String?, subdirectory subpath: String?) -> [NSURL]? {
return CFBundleCopyResourceURLsOfType(_bundle, ext?._cfObject, subpath?._cfObject)?._unsafeTypedBridge()
}
open func urls(forResourcesWithExtension ext: String?, subdirectory subpath: String?, localization localizationName: String?) -> [NSURL]? {
return CFBundleCopyResourceURLsOfTypeForLocalization(_bundle, ext?._cfObject, subpath?._cfObject, localizationName?._cfObject)?._unsafeTypedBridge()
}
// -----------------------------------------------------------------------------------
// MARK: - Path Resource Lookup - Class
open class func path(forResource name: String?, ofType ext: String?, inDirectory bundlePath: String) -> String? {
return Bundle.url(forResource: name, withExtension: ext, subdirectory: bundlePath, in: URL(fileURLWithPath: bundlePath))?.path ?? nil
}
open class func paths(forResourcesOfType ext: String?, inDirectory bundlePath: String) -> [String] {
// Force-unwrap path, beacuse if the URL can't be turned into a path then something is wrong anyway
return urls(forResourcesWithExtension: ext, subdirectory: bundlePath, in: NSURL(fileURLWithPath: bundlePath))?.map { $0.path! } ?? []
}
// -----------------------------------------------------------------------------------
// MARK: - Path Resource Lookup - Instance
open func path(forResource name: String?, ofType ext: String?) -> String? {
return self.url(forResource: name, withExtension: ext, subdirectory: nil)?.path
}
open func path(forResource name: String?, ofType ext: String?, inDirectory subpath: String?) -> String? {
return self.url(forResource: name, withExtension: ext, subdirectory: subpath)?.path
}
open func path(forResource name: String?, ofType ext: String?, inDirectory subpath: String?, forLocalization localizationName: String?) -> String? {
return self.url(forResource: name, withExtension: ext, subdirectory: subpath, localization: localizationName)?.path
}
open func paths(forResourcesOfType ext: String?, inDirectory subpath: String?) -> [String] {
// Force-unwrap path, beacuse if the URL can't be turned into a path then something is wrong anyway
return self.urls(forResourcesWithExtension: ext, subdirectory: subpath)?.map { $0.path! } ?? []
}
open func paths(forResourcesOfType ext: String?, inDirectory subpath: String?, forLocalization localizationName: String?) -> [String] {
// Force-unwrap path, beacuse if the URL can't be turned into a path then something is wrong anyway
return self.urls(forResourcesWithExtension: ext, subdirectory: subpath, localization: localizationName)?.map { $0.path! } ?? []
}
// -----------------------------------------------------------------------------------
// MARK: - Localized Strings
open func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
let localizedString = CFBundleCopyLocalizedString(_bundle, key._cfObject, value?._cfObject, tableName?._cfObject)!
return localizedString._swiftObject
}
// -----------------------------------------------------------------------------------
// MARK: - Other
open var bundleIdentifier: String? {
return CFBundleGetIdentifier(_bundle)?._swiftObject
}
open var infoDictionary: [String : Any]? {
let cfDict: CFDictionary? = CFBundleGetInfoDictionary(_bundle)
return _SwiftValue.fetch(cfDict) as? [String : Any]
}
open var localizedInfoDictionary: [String : Any]? {
let cfDict: CFDictionary? = CFBundleGetLocalInfoDictionary(_bundle)
return _SwiftValue.fetch(cfDict) as? [String : Any]
}
open func object(forInfoDictionaryKey key: String) -> Any? {
if let localizedInfoDictionary = localizedInfoDictionary {
return localizedInfoDictionary[key]
} else {
return infoDictionary?[key]
}
}
open func classNamed(_ className: String) -> AnyClass? { NSUnimplemented() }
open var principalClass: AnyClass? { NSUnimplemented() }
open var preferredLocalizations: [String] {
return Bundle.preferredLocalizations(from: localizations)
}
open var localizations: [String] {
let cfLocalizations: CFArray? = CFBundleCopyBundleLocalizations(_bundle)
let nsLocalizations = _SwiftValue.fetch(cfLocalizations) as? [Any]
return nsLocalizations?.map { $0 as! String } ?? []
}
open var developmentLocalization: String? {
let region = CFBundleGetDevelopmentRegion(_bundle)!
return region._swiftObject
}
open class func preferredLocalizations(from localizationsArray: [String]) -> [String] {
let cfLocalizations: CFArray? = CFBundleCopyPreferredLocalizationsFromArray(localizationsArray._cfObject)
let nsLocalizations = _SwiftValue.fetch(cfLocalizations) as? [Any]
return nsLocalizations?.map { $0 as! String } ?? []
}
open class func preferredLocalizations(from localizationsArray: [String], forPreferences preferencesArray: [String]?) -> [String] {
let localizations = CFBundleCopyLocalizationsForPreferences(localizationsArray._cfObject, preferencesArray?._cfObject)!
return localizations._swiftObject.map { return ($0 as! NSString)._swiftObject }
}
open var executableArchitectures: [NSNumber]? {
let architectures = CFBundleCopyExecutableArchitectures(_bundle)!
return architectures._swiftObject.map() { $0 as! NSNumber }
}
}