I have a large file saved in iCloud drive. I need just a portion of that file.
func ubiquitousData(file: URL, offset: UInt64, size: UInt64) async -> Data {
// downloads just the portion of the ubiquitous `file`.
}
FileManager already has an api that downloads the full file. Is there a way to download just a portion of the file?
Post
Replies
Boosts
Views
Activity
@discardableResult func doSomething() -> Bool {
// does something
return true
}
This function can be called in the following ways:
doSomething()
let didSucceed = doSomething()
Is there a way to differentiate the two from inside the doSomething() function, as in, is there a way to know if the caller is using the result?
I'm using a file descriptor to write into a file. I've encountered a problem where if the underlying file is removed or recreated, the file descriptor becomes unstable. I have no reliable way to confirm if it's writing on the expected file.
let url = URL(fileURLWithPath: "/path/")
try FileManager.default.removeItem(at: url)
FileManager.default.createFile(atPath: url.path, contents: .empty)
let filePath = FilePath(url.path)
var fileDescriptor = try FileDescriptor.open(filePath, .readWrite)
// The file is recreated - may be done from a different process.
try FileManager.default.removeItem(at: url) // L9
FileManager.default.createFile(atPath: url.path, contents: .empty) // L10
let dataToWrite = Data([1,1,1,1])
try fileDescriptor.writeAll(dataToWrite) // L13
let dataWritten = try Data(contentsOf: url)
print(dataToWrite == dataWritten) // false
I would expect L13 to result in an error. Given it doesn't:
Is there a way to determine where fileDescriptor is writing?
Is there a way to ensure that fileDescriptor is writing the content in the expected filePath?
The performance of DataProtocol.firstRange(of:) and Collection.firstRange(of:) is different.
func testSearch(dataSize: Int = 10_000_000, segmentSize: Int = 1000) {
let query = Data([1,1,1])
let data = Data(repeating: 0, count: dataSize)
let segments = stride(from: 0, to: dataSize, by: segmentSize)
// Search for `query` in `data` using `Data.firstRange(of:`
var date = Date.now
let result1 = segments.compactMap({ i in
data[i..<i+segmentSize].firstRange(of: query)
})
print(-date.timeIntervalSinceNow) // 1 sec.
// Search for `query` in `data` using `Collection.firstRange(of:`
date = .now
let result2 = segments.compactMap({ i in
data[i..<i+segmentSize].search(for: query)
})
print(-date.timeIntervalSinceNow) // 4 secs.
assert(result1 == result2)
}
extension Collection {
func search<T: Collection>(for query: T) -> Range<Index>?
where T.Element == Element, Element: Equatable {
firstRange(of: query)
}
}
To fix, I’m explicitly casting it to Data.
extension Collection {
func search<T: Collection>(for query: T) -> Range<Index>?
where T.Element == Element, Element: Equatable {
if let data = self as? Data, let query = query as? Data {
return data.firstRange(of: query) as? Range<Index>
} else {
return firstRange(of: query)
}
}
}
This fixes, but doesn’t scale well. Given the method signature is same, how can I write the search function such that it picks up the one in DataProtocol?
In my testing, the search results of both are same. Besides the performance, is there any other difference?
To restrict outgoing connections, I've ensured that the following key in not present in the entitlement file:
<key>com.apple.security.network.client</key>
<true/>
The api calls made using URLSession and WKWebView are restricted as expected, but the same is not the case with MKMapView. The map content and the directions api are able to make outgoing network calls.
Please let me know if it's possible to reliably restrict outgoing network connections in a sandboxed app?
An iOS app running in simulator has complete access to the Mac's file system:
// Files in protected directory like Desktop, Documents, Calendar, etc will need additional permissions.
let filesInSystem = FileManager.default.enumerator(at: .currentDirectory(), includingPropertiesForKeys: nil)?.allObjects
This isn't the case when running in device as the app is sandboxed. Is the same possible when running in simulator? More specifically, is there a way to restrict access to the Mac's file system when running an app in the Simulator? This is particularly useful when trying out binaries/frameworks that are not open sourced.
I'm trying to use the resourceLoader of an AVAsset to progressively supply media data. Unable to because the delegate asks for the full content requestsAllDataToEndOfResource = true.
class ResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
if let ci = loadingRequest.contentInformationRequest {
ci.contentType = // public.mpeg-4
ci.contentLength = // GBs
ci.isEntireLengthAvailableOnDemand = false
ci.isByteRangeAccessSupported = true
}
if let dr = loadingRequest.dataRequest {
if dr.requestedLength > 200_000_000 {
// memory pressure
// dr.requestsAllDataToEndOfResource is true
}
}
return true
}
}
Also tried using a fragmented MP4 created using AVAssetWriter. But didn't work. Please let me know if it's possible for the AVAssetResourceLoader to not ask for the full content?
Using Xcode (or Instruments), is there a way to know all the functions/symbols that are touched by a line of code?
struct Test {
private func intro() {
}
func partOne() {
intro()
}
func partTwo() {
partOne()
}
func partThree() {
partTwo()
print(credits)
}
private var credits: String {
""
}
}
let test = Test()
test.partTwo() // partTwo, partOne, intro
test.partThree() // partThree, partTwo, partOne, intro, credits
I noticed that I need not set the NEVPNProtocolIKEv2's passwordReference if I supplied the userName and password via the options argument in startVPNTunnel.
Supply password using passwordReference (requires use of Keychain):
func connect(userName: String, password: String, serverAddress: String) async throws {
saveToKeychain(key: "VPN_Password", value: password)
let passwordReference = keychainReference(key: "VPN_Password")
let vpn = NEVPNManager.shared()
try await vpn.loadFromPreferences()
let pc = NEVPNProtocolIKEv2()
pc.serverAddress = serverAddress
pc.authenticationMethod = .none
pc.username = userName
pc.passwordReference = passwordReference
pc.useExtendedAuthentication = true
vpn.protocolConfiguration = pc
vpn.isEnabled = true
try await vpn.saveToPreferences()
try await vpn.loadFromPreferences()
try vpn.connection.startVPNTunnel()
}
Supply password using options parameter in startVPNTunnel:
func connect(userName: String, password: String, serverAddress: String) async throws {
let vpn = NEVPNManager.shared()
try await vpn.loadFromPreferences()
let pc = NEVPNProtocolIKEv2()
pc.serverAddress = serverAddress
pc.authenticationMethod = .none
pc.useExtendedAuthentication = true
vpn.protocolConfiguration = pc
vpn.isEnabled = true
try await vpn.saveToPreferences()
try await vpn.loadFromPreferences()
try vpn.connection.startVPNTunnel(options: [NEVPNConnectionStartOptionUsername: userName, NEVPNConnectionStartOptionPassword: password])
}
Is one preferred over the other? I'm inclined to use the second one as it doesn't require the (additional) use of the Keychain. Are there any drawbacks in doing do?
I'm using NEVPNProtocolIKEv2 to configure NEVPNManager:
func connect(userName: String, passwordReference: Data, serverAddress: String) async throws {
let vpn = NEVPNManager.shared()
try await vpn.loadFromPreferences()
let pc = NEVPNProtocolIKEv2()
pc.serverAddress = serverAddress
pc.authenticationMethod = .none
pc.username = userName
pc.passwordReference = passwordReference
pc.useExtendedAuthentication = true
vpn.protocolConfiguration = pc
vpn.isEnabled = true
try await vpn.saveToPreferences()
try await vpn.loadFromPreferences()
try vpn.connection.startVPNTunnel()
}
Is there a parameter I can modify so that the IP address of the client appears different every few minutes?