I am trying to save the image from a URL from my server:
let urlString = "http://someValidUrlToAnImage.png"
let url = URL(string: urlString )
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url!) {
if let image = UIImage(data: data) {
DispatchQueue.main.async {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
print( "Image saved !!!!" )
}
}
}
}
It was working fine before, but now I am getting this error:
Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "(originator doesn't have entitlement com.apple.runningboard.assertions.webkit AND originator doesn't have entitlement com.apple.multitasking.systemappassertions)" UserInfo={NSLocalizedFailureReason=(originator doesn't have entitlement com.apple.runningboard.assertions.webkit AND originator doesn't have entitlement com.apple.multitasking.systemappassertions)}>
I am testing it via Xcode and USB cable.
I have added all the entitlements to Xcode's plist and to the AppStoreConnect site.
What could be causing this error?
Related
I'm creating an app with App Extension and I'm having trouble uploading files to firebase storage.
I choose a photo that I chose from the Photos application or another application for my own application by pressing the share button.
I am getting the URL of the selected photo in ShareViewController.
if let items = (self.extensionContext?.inputItems.first as? NSExtensionItem)?.attachments {
let contentType = kUTTypeData as String
for item in items {
item.loadItem(forTypeIdentifier: contentType, options: nil) { url, error in
if let path = url as? NSURL {
URLs.append(path.absoluteString!)
}
else {}
}
}
}
I'm trying to upload the URLs I get this way to firebase storage.
let uploadTask = riversRef.putFile(from: URLs[0], metadata: nil) { metadata, error in
guard let metadata = metadata else {
return
}
...
}
There is a problem with the URL of the selected photo but I can't quite understand it. I can get the size, name and other properties of the photo from the URL. I can even copy this photo to another directory with FileManager. I'm getting the URL from FileManager but still getting the same error. But when I try to install I get the following error.
Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, please check the server response." UserInfo={bucket=appBucketName, _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundUploadTask <9381D3C6-241C-4737-9589-BA5A7CFAF9E4>.<1>, object=PATH/6B36F026-CD6E-4E00-8A19-C530DC606674.jpg, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"BackgroundUploadTask <9381D3C6-241C-4737-9589-BA5A7CFAF9E4>.<1>"
), NSLocalizedDescription=An unknown error occurred, please check the server response., ResponseErrorDomain=NSURLErrorDomain, ResponseErrorCode=-995}
Solutions I tried;
I will not use putData.
I tried App Groups. I already have the URL of the file. I need to install directly but it doesn't work.
extension FileManager {
func documentsDirectory() -> URL {
let path = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.name")
return path!
}
func uploadPath(srcURL: URL, name: String, completion: #escaping ((_ filePath: URL?) -> Void)) {
do {
let path = documentsDirectory().appendingPathComponent("tempory")
try FileManager.default.createDirectory(atPath: path.relativePath, withIntermediateDirectories: true, attributes: nil)
let fullPath = path.appendingPathComponent(name)
try FileManager.default.copyItem(at: srcURL, to: fullPath)
completion(fullPath)
}
catch {
completion(nil)
}
}
}
Note: I am using Firebase emulator and Xcode simulator. I don't have any problems with the main application.
If there is missing information or incorrect information, please warn, I will correct it. Thank you for your help in advance.
I am following the doc here: https://docs.agora.io/en/Voice/rtc_recording_apple?platform=iOS and implementing a basic recording. This is my code:
func startRecording(){
let filename = getDocumentsDirectory().appendingPathComponent("\(APP_NAME)\(now()).WAV")
let str = String(describing: filename)
self.recordingPath = str
agoraKit?.startAudioRecording(str, quality: .high)
}
func stopRecording(){
agoraKit?.stopAudioRecording()
// get audio file
guard let audioUrl = URL(string: self.recordingPath) as? URL else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0 ) { [weak self] in
// getdata
do {
let myData = try Data(contentsOf: audioUrl)
print(myData.count, myData)
} catch {
print(error)
}
}
}
private func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
But I am getting error: The file “Whisper1608949569.WAV” couldn’t be opened because there is no such file
Full message:
file:///var/mobile/Containers/Data/Application/1F682ABD-153C-4DFD-BFF4-
02C1CE6F9A4C/Documents/Whisper1608949569.WAV
Error Domain=NSCocoaErrorDomain Code=260 "The file “Whisper1608949569.WAV” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/1F682ABD-153C-4DFD-BFF4-02C1CE6F9A4C/Documents/Whisper1608949569.WAV, NSUnderlyingError=0x281e33f60 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Am I not accessing the file correctly?
This is how I have initialized the agora client:
self.agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: AppID, delegate: self)
agoraKit?.delegate = self
agoraKit?.enableWebSdkInteroperability(true)
// sample loudest speaker every second
agoraKit?.enableAudioVolumeIndication(1000, smooth: 3, report_vad: true)
agoraKit?.enableAudio()
// config for livecast to start
agoraKit?.setChannelProfile(.liveBroadcasting)
// set framrate and HD/SD
agoraKit?.setVideoEncoderConfiguration( CONFIG_PRODUCTION )
//agoraKit?.setDefaultAudioRouteToSpeakerphone(true)
I just checked out the documentation referenced from the doc you're using and it says the method startAudioRecording(filepath, quality: quality) is now deprecated, and you should instead use this method with the additional sampleRate parameter:
https://docs.agora.io/en/Voice/API%20Reference/oc/Classes/AgoraRtcEngineKit.html#//api/name/startAudioRecording:sampleRate:quality:
Also check that the returned value of startAudioRecording and stopAudioRecording returns 0, meaning success.
If your channel name contains special characters (colons, slashes) recording will silently fail and no file will be produced.
It seems Agora uses the channel name when creating the temporary file.
I'm making a game on iPad (v10.2.1) with Xcode(version 8.2.1) and while I'm trying to save some data in documents folder in the sandbox, I found that all ways I tried failed: createDirectory and createFile(using file manager), and writeToUrl(using NSData). I ran the program on 2 iPads and 1 iPhone and no success.
I was able to read from a plist I created, and convert it to a dictionary, using the function convertDataFrom().
I'm new to data persistence or file manipulation and my game stuck here. would appreciate any help!
func loadData()->NSDictionary{
let fm = FileManager()
let sourceUrl = Bundle.main.url(forResource: "Data", withExtension: "plist")!
var appSupportDir = fm.urls(for: .documentDirectory, in: .userDomainMask).first! as? NSURL
appSupportDir = appSupportDir!.appendingPathComponent("UserData", isDirectory: true) as NSURL?
let urlForSave = (appSupportDir!.appendingPathComponent("Data.plist"))!
//load data, or if file doesn't exist yet, create one
var isDirectory: ObjCBool = false
if fm.fileExists(atPath: urlForSave.absoluteString, isDirectory: &isDirectory) {
let data = convertDataFrom(url: urlForSave)
print("data file exists")
print(isDirectory)
return data as NSDictionary
} else {
do { try fm.createDirectory(atPath: appSupportDir!.absoluteString!, withIntermediateDirectories: true, attributes: nil) }catch let Error {
print("create directory failed")
print(Error)
}
let originalData = NSData.init(contentsOf: sourceUrl)
print("\(urlForSave)")
do { try originalData?.write(toFile: urlForSave.absoluteString, options: .atomic) } catch let Error {
print(Error)
}
if (!fm.createFile(atPath: urlForSave.absoluteString, contents: originalData as Data?, attributes: nil)) {
fatalError("file creation failed")
}
let data = convertDataFrom(url: urlForSave)
print("\(data)")
print(isDirectory)
return data as NSDictionary
}
}
func convertDataFrom(url: URL)->Dictionary<String, Any> {
let dictionary = NSDictionary.init(contentsOf: url) as! Dictionary<String, Any>
return dictionary
}
Error messages for "createDirectory": Error Domain=NSCocoaErrorDomain
Code=513 "You don’t have permission to save the file “UserData” in the
folder “Documents”."
UserInfo={NSFilePath=file:///var/mobile/Containers/Data/Application/F7F41E0D-D3F6-489B-A59E-B7AC401EC402/Documents/UserData/,
NSUnderlyingError=0x174053f50 {Error Domain=NSPOSIXErrorDomain Code=1
"Operation not permitted"}}
file:///var/mobile/Containers/Data/Application/F7F41E0D-D3F6-489B-A59E-B7AC401EC402/Documents/UserData/Data.plist
and for "createFile" (fatalError if createFile fails) Error
Domain=NSCocoaErrorDomain Code=4 "The file “Data.plist” doesn’t
exist."
UserInfo={NSFilePath=file:///var/mobile/Containers/Data/Application/F7F41E0D-D3F6-489B-A59E-B7AC401EC402/Documents/UserData/Data.plist,
NSUnderlyingError=0x174055bd0 {Error Domain=NSPOSIXErrorDomain Code=2
"No such file or directory"}} fatal error: file creation failed: file
/Users/chanwu/Desktop/Math_DownStairs/Math_DownStairs/
Your code checks to see if urlForSave (the final file) exists, and if it doesn't, you then try to create the UserData directory.
If the final file doesn't exist, but the UserData directory does, I would expect the exact outcome you describe.
You should probably change your test to see if the UserData directory exists instead of testing for the final file. That way if the directory doesn't exist you'll create it, and then call write(toFile:), which will create the file if it doesn't exist.
Alamofire 3.5.0, Swift2.2
I'm downloading ZIP files with the Alamofire download method, I've noticed that when I'm starting download process and apps goes background than the download fails with following error:
----------------------
error Optional(Error Domain=NSCocoaErrorDomain Code=4
"“CFNetworkDownload_pZ56nc.tmp” couldn’t be moved to “courses”
because either the former doesn't exist, or the folder containing
the latter doesn't exist." UserInfo=
{NSSourceFilePathErrorKey=
/private/var/mobile/Containers/Data/Application/[UUID]/tmp/CFNetworkDownload_pZ56nc.tmp,
NSUserStringVariant=(
Move
),
NSDestinationFilePath=
/var/mobile/Containers/Data/Application/[UUID]/Library/courses/course_302.zip,
NSFilePath=
/private/var/mobile/Containers/Data/Application/[UUID]/tmp/CFNetworkDownload_pZ56nc.tmp,
NSUnderlyingError=0x13f52f990 {Error Domain=NSPOSIXErrorDomain
Code=2 "No such file or directory"}})
----------------------
this is the code to download a file:
//...
var userLibraryPath:String = {
return NSSearchPathForDirectoriesInDomains(.LibraryDirectory, .UserDomainMask, true)[0]
}()
//...
let _coursePath:NSURL = NSURL(string: "file://\(userLibraryPath)/)")!
//...
let zipURL = _coursePath.URLByAppendingPathComponent("course_\(courseId).zip")
//if file exists destroy it
if let zipPath = zipURL?.path where NSFileManager.defaultManager().fileExistsAtPath(zipPath) {
do {
try NSFileManager.defaultManager().removeItemAtPath(zipPath)
} catch let error as NSError {
print(error)
}
}
//
let downloadRequest = Alamofire.download(Router.download(courseId), destination: { (url:NSURL, urlResponse:NSHTTPURLResponse) -> NSURL in
//
return zipURL!
//
}).progress({ (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
//
let progress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)
dispatch_async(GlobalMainQueue, {
self.notifyDownloadProgress(courseId, progress: progress)
})
}).response(completionHandler: { (request:NSURLRequest?, response:NSHTTPURLResponse?, data:NSData?, error:NSError?) in
self.removeFromQueue(courseId)
print("response")
print("----------------------")
print("error \(error)")
print("----------------------")
//here I would try to extract it
})
UPDATE I've just tested on iPhone 5 fresh install of the app and it doesn't have to go to background (e.g. via home button) to fail, it fails on the very first load (and any subsequent) untill after the app is killed and reopened.
Why is the "/private" bit added to the path? What am I doing wrong here?
And indeed it was a "No such file or directory" error.
When I've added:
//
let downloadRequest = Alamofire.download(Router.download(courseId), destination: { (url:NSURL, urlResponse:NSHTTPURLResponse) -> NSURL in
let course = zipURL!.URLByDeletingLastPathComponent!.path!
let fm = NSFileManager.defaultManager()
var isDir:ObjCBool = false
if(fm.fileExistsAtPath(path, isDirectory: &isDir) == false){
//doesnt exist
do {
try fm.createDirectoryAtPath(path, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
//
print(error)
}
}
return zipURL!
//
})
After transferring a file from iPhone to Apple Watch I get the Error
Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"
What do I do wrong? These are the code snippets:
iPhone ViewController
func makeAction () {
let url = NSURL.fileURL(withPath: fileArray[0].object(at: 2) as! String)
var applicationDict = Dictionary<String, Array<AnyObject>>()
applicationDict["fileArray"] = fileArray
WCSession.default().transferFile(url, metadata: applicationDict)
}
Watch InterfaceController
func session(_ session: WCSession, didReceive file: WCSessionFile) {
DispatchQueue.main.async(execute: { () -> Void in
print("RECEIVED")
var applicationDict = Dictionary<String, Array<AnyObject>>()
applicationDict = file.metadata as! Dictionary<String, Array<AnyObject>>
self.fileArray = applicationDict["fileArray"]!
self.fileList = self.fileArray
let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let tempDocsDir = dirPaths[0] as String
let docsDir = tempDocsDir.appending("/")
let filemgr = FileManager.default
do {
let fileName = self.fileArray[0].object(at: 1) as! String
try filemgr.moveItem(atPath: file.fileURL.path, toPath: docsDir + fileName)
} catch let error as NSError {
print("Error moving file: \(error.description)")
}
self.loadTableData()
})
}
Full Error Message
Error moving file: Error Domain=NSCocoaErrorDomain Code=4
"“5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3” couldn’t be moved to “Documents” because either the former doesn't
exist, or the folder containing the latter doesn't exist."
UserInfo={NSSourceFilePathErrorKey=/Users/pknapp/Library/Developer/CoreSimulator/Devices/950FC0DA-C245-4326-8777-80CE765AF655/data/Containers/Data/PluginKitPlugin/73C0D94F-483C-4426-B052-001E8837D83A/Documents/Inbox/com.apple.watchconnectivity/FCE7E6CB-2452-4E0A-9AFF-F5B3A51A0DE8/Files/0B96CCB0-A2E1-418B-9859-97C22238A5F5/5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3, NSUserStringVariant=(
Move ), NSFilePath=/Users/pknapp/Library/Developer/CoreSimulator/Devices/950FC0DA-C245-4326-8777-80CE765AF655/data/Containers/Data/PluginKitPlugin/73C0D94F-483C-4426-B052-001E8837D83A/Documents/Inbox/com.apple.watchconnectivity/FCE7E6CB-2452-4E0A-9AFF-F5B3A51A0DE8/Files/0B96CCB0-A2E1-418B-9859-97C22238A5F5/5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3, NSDestinationFilePath=/Users/pknapp/Library/Developer/CoreSimulator/Devices/950FC0DA-C245-4326-8777-80CE765AF655/data/Containers/Data/PluginKitPlugin/73C0D94F-483C-4426-B052-001E8837D83A/Documents/5d1392cd-acac-4b99-abf5-50062e12dc14_95de54df-69b1-43df-bb90-cfac6fed3677.mp3, NSUnderlyingError=0x7b776110 {Error Domain=NSPOSIXErrorDomain Code=2
"No such file or directory"}}
The documentation for didReceiveFile notes:
File: The object containing the URL of the file and any additional information. If you want to keep the file referenced by this parameter, you must move it synchronously to a new location during your implementation of this method. If you do not move the file, the system deletes it after this method returns.
So make sure to not async in this method before moving the file to a location your app has access to.
Alright, got it. putting this in an async dispatch was wrong. Without ist -> work perfectly. Please go ahead, nothing to see here :)