I am getting "File don't exists" error in Move Content function. I have shared the console outputs below. How can I move a file in the document picker into a file of my own application?
When the user selects a file from Document Picker, I want to move the selected file to the SafeFile folder in the Folder application on the iPhone. I couldn't do this.
Move Content:
func moveContentMyApp(atPath: String, toPath: String, myFile: MyFile) {
let emptyFile = MyFile(fileName: "", fileExtension: "", textForFile: "", image: nil, typeOfFile: "", isLock: false, folderIcon: .empty, fileCreateDate: "", fileSize: 0, localPath: "")
guard let originURL = takeMainDirectoryURL(addPath: atPath, myFile: emptyFile) else {
return
}
guard let destinationURL = takeMainDirectoryURL(addPath: toPath, myFile: myFile) else {
return
}
print("origin2: \(originURL)")
print("destination2: \(destinationURL)")
if manager.fileExists(atPath: originURL.path) {
do {
try manager.moveItem(atPath: originURL.path, toPath: destinationURL.path)
} catch let error {
print("Error Description: \(error.localizedDescription)")
}
} else {
print("File don't exists")
}
}
Move Function:
func moveContentOnMyApp() {
print("origin path: \(originPath)")
print("destinationPath: \(destinationPath)")
myAppFileManager.moveContentMyApp(atPath: originPath, toPath: destinationPath, myFile: selectedFile)
originPath = ""
destinationPath = ""
takeArrayOfItems()
}
File Importer:
.fileImporter(isPresented: $isOpenDocumentPicker, allowedContentTypes: [.image, .jpeg, .png, .gif, .pdf], onCompletion: { (res) in
do {
let fileURL = try res.get()
if fileURL.startAccessingSecurityScopedResource() {
safeFileVM.setOriginPath(currentPath: fileURL.path)
safeFileVM.selectedFile.fileName = "asikarti"
safeFileVM.selectedFile.fileExtension = "pdf"
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
safeFileVM.setDestinationPath(currentPath: currentLocation)
safeFileVM.moveContentOnMyApp()
}
} else {
print("olmuyor")
}
fileURL.stopAccessingSecurityScopedResource()
} catch {
print("error")
}
})
Console:
origin path: /private/var/mobile/Containers/Shared/AppGroup/5C8D117E-13BB-46C3-80DB-27F700A54680/File Provider Storage/HES/asikarti.pdf
destinationPath: /test
origin2: file:///var/mobile/Containers/Data/Application/34FD7C1C-3478-41B8-B7F0-AC2D32C5DAC0/Documents//private/var/mobile/Containers/Shared/AppGroup/5C8D117E-13BB-46C3-80DB-27F700A54680/File%20Provider%20Storage/HES/asikarti.pdf
destination2: file:///var/mobile/Containers/Data/Application/34FD7C1C-3478-41B8-B7F0-AC2D32C5DAC0/Documents//test/asikarti.pdf
File don't exists
Related
I have a model with data string of name and a bool of UE. I'm trying to display item.name whenever UE is true. My issue is when whenever I run the code the data doesn't seem to read the UE. I got an error displaying the item.UE as a text view. The data that I am getting it from is from a database the item.name works without the conditional.
struct AttendingUsersView: View {
#ObservedObject var model = UserViewModel()
var body: some View {
VStack {
List (model.list) { item in
if item.UE == true {
Text(item.name)
} else {
Text("This isnt working")
}
}
DismissButton
}
}
I've tried displaying the item.UE to see what it would display but I get an error saying "No exact matches in call to initializer".
UserViewModel file
class UserViewModel: ObservableObject {
#Published var list = [Username]()
func addData(name: String, UE: Bool) {
//get a reference to the database
let db = Firestore.firestore()
// Add a new document in collection "username"
db.collection("usernames").document(UserDefaults.standard.object(forKey: "value") as! String).setData([
// MARK: Change the parameters to the users inputed choices
"name": name,
"UE": UE
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
}
func getData() {
//get a reference to the database
let db = Firestore.firestore()
//Read the documents at a specific path
db.collection("usernames").getDocuments { snapshot, error in
//checking for errors
if error == nil {
//no errors
if let snapshot = snapshot {
// update
DispatchQueue.main.async {
// Get all the documents and create usernames
self.list = snapshot.documents.map { d in
//Create a Username
return Username(id: d.documentID, name: d["name"] as? String ?? "", UE: (d["UE"] != nil)) //cast as a string and if not found return as a empty string
}
}
}
} else {
//Handle the error
}
}
}
}
Username model
struct Username: Identifiable {
var id: String
var name: String
var ue: Bool
}
Try this, with fixes for your ue in your getData, and
in the view display.
struct ContentView: View {
var body: some View {
AttendingUsersView()
}
}
struct AttendingUsersView: View {
#StateObject var model = UserViewModel() // <-- here
var body: some View {
VStack {
List (model.list) { item in
if item.ue { // <-- here
Text(item.name)
} else {
Text("This is working ue is false")
}
}
// DismissButton
}
}
}
class UserViewModel: ObservableObject {
// for testing
#Published var list:[Username] = [Username(id: "1", name: "item-1", ue: false),
Username(id: "2", name: "item-2", ue: true),
Username(id: "3", name: "item-3", ue: false)]
func addData(name: String, UE: Bool) {
//get a reference to the database
let db = Firestore.firestore()
// Add a new document in collection "username"
db.collection("usernames").document(UserDefaults.standard.object(forKey: "value") as! String).setData([
// MARK: Change the parameters to the users inputed choices
"name": name,
"UE": UE
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
}
func getData() {
//get a reference to the database
let db = Firestore.firestore()
//Read the documents at a specific path
db.collection("usernames").getDocuments { snapshot, error in
//checking for errors
if error == nil {
//no errors
if let snapshot = snapshot {
// update
DispatchQueue.main.async {
// Get all the documents and create usernames
self.list = snapshot.documents.map { d in
//Create a Username
// -- here, ue:
return Username(id: d.documentID, name: d["name"] as? String ?? "", ue: (d["UE"] != nil)) // <-- here ue:
}
}
}
} else {
//Handle the error
}
}
}
}
struct Username: Identifiable {
var id: String
var name: String
var ue: Bool
}
Here is how I add new entity.
func addCountry(name: String, code: String, flagImageUri: String?, wikiDataId: String) {
let newCountry = CountryEntity(context: container.viewContext)
newCountry.name = name
newCountry.code = code
newCountry.flagImageUri = flagImageUri
newCountry.wikiDataId = wikiDataId
save()
}
Here is my data:
However when I use the add function in my view, I got this error:
CoreData: error: +[CountryEntity entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
And this is my button:
Button(action: {
country.isFaved = !country.isFaved
coreDataModel.addCountry(name: country.name, code: country.code, flagImageUri: country.flagImageUri, wikiDataId: country.wikiDataId)
}) {
Image(systemName: "star.fill")
.foregroundColor(country.isFaved ? .black : .white)
.scaledToFit()
}
This is the whole class. I'm fetching, saving ,adding and deleting all data here. I did everything like the video I watched in youtube.
class DataController: ObservableObject {
let container = NSPersistentContainer(name: "CountryCoreData")
#Published var savedCountries: [CountryEntity] = []
init() {
container.loadPersistentStores(completionHandler: { _, error in
if let error = error {
print("CoreData failed to load: \(error.localizedDescription)")
} else {
print("Successfully loaded")
}
})
}
func fetchCountries() -> [CountryEntity]? {
let request = NSFetchRequest<CountryEntity>(entityName: "CountryEntity")
do {
let fetchedCountries = try container.viewContext.fetch(request)
return fetchedCountries
} catch {
print("Something went wrong while data fetching \(error)")
return nil
}
}
func delete(code: String) {
guard let fetchedCountries = fetchCountries() else { return }
for country in fetchedCountries {
if country.code!.contains(code) {
container.viewContext.delete(country)
save()
}
}
}
func addCountry(name: String, code: String, flagImageUri: String?, wikiDataId: String) {
let newCountry = CountryEntity(context: container.viewContext)
print("OSMAN")
newCountry.name = name
newCountry.code = code
newCountry.flagImageUri = flagImageUri
newCountry.wikiDataId = wikiDataId
save()
}
func save() {
do {
try container.viewContext.save()
fetchCountries()
} catch {
print("Error while saving the data: \(error)")
}
}
}
How can I solve this problem?
I'm using QBImagePicker. I tried to get image file name, but it's very difficult. What can I do for that? I don't know it.
func qb_imagePickerController(_ imagePickerController: QBImagePickerController!, didFinishPickingAssets assets: [Any]!) {
let requestOptions = PHImageRequestOptions()
requestOptions.resizeMode = PHImageRequestOptionsResizeMode.exact
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryMode.highQualityFormat
// this one is key
requestOptions.isSynchronous = true
for asset in assets {
if ((asset as AnyObject).mediaType == PHAssetMediaType.image) {
PHImageManager.default().requestImage(for: asset as! PHAsset, targetSize: PHImageManagerMaximumSize, contentMode: PHImageContentMode.default, options: requestOptions, resultHandler: {
(pickedImage, info) in
self.selectImage.image = self.resizeImage(getImageView: self.selectImage, originImage: pickedImage!)
})
}
}
imagePickerController.dismiss(animated: true, completion: nil)
}
Try this
if let fileName = Asset.value(forKey: "filename") as? String{
print(fileName)
}
let originalName = PHAssetResource.assetResources(for: asset).first?.originalFilename
print("original File name \(originalName)")
I'm facing the issue while saving the video to the directory.
I'm using following code:-
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let dataPath = documentsDirectory.appendingPathComponent("MyFolder")
do {
try FileManager.default.createDirectory(atPath: dataPath.path, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
print("Error creating directory: \(error.localizedDescription)")
}
let filePath="\(dataPath.absoluteString)video.mp4";
DispatchQueue.main.async(execute: {
urlData?.write(toFile: filePath, atomically: true);
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: NSURL(fileURLWithPath: filePath) as URL)
}) { completed, error in
if completed {
print("Video is saved!")
// self.videoAlertMeaage(isError: false)
}else{
// self.videoAlertMeaage(isError: true)
}
}
})
I am trying to write data that is inputted by a user via UITextField to a text file. I am successfully able to do this by the code I have written below. However, when I tried to save more data it will replace the existing data in the textfile with the new data that is being saved. for example, if I save the string 'hello world' and then save another string saying 'bye'. I will only see the string 'bye' in the textfile. Is there a way I can modify my code so I can see 'hello world' on one line of the textile and 'bye' on another.
#IBAction func btnclicked(_ sender: Any) {
self.savedata(value: answer.text!)
}
func savedata (value: String){
let fileName = "Test"
let DocumentDirURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let fileURL = DocumentDirURL.appendingPathComponent(fileName).appendingPathExtension("txt")
print("FilePath: \(fileURL.path)")
let writeString = NSString(string: answer.text!)
do {
// Write to the file
try writeString.write(to: fileURL, atomically: true, encoding: String.Encoding.utf8.rawValue)
} catch let error as NSError {
print("Failed writing to URL: \(fileURL), Error: " + error.localizedDescription)
}
}
Here is an example using FIleHandler, adapted to Swift 3, from here (of course you should add all the error handling code that's missing in my example) :
let dir = FileManager.default.urls(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first!
let fileurl = dir.appendingPathComponent("log.txt")
let string = "\(NSDate())\n"
let data = string.data(using: .utf8, allowLossyConversion: false)!
if FileManager.default.fileExists(atPath: fileurl.path) {
if let fileHandle = try? FileHandle(forUpdating: fileurl) {
fileHandle.seekToEndOfFile()
fileHandle.write(data)
fileHandle.closeFile()
}
} else {
try! data.write(to: fileurl, options: Data.WritingOptions.atomic)
}
do {
let fileHandle = try FileHandle(forWritingTo:pathWithFileName)
fileHandle.seekToEndOfFile()
let oldData = try String(contentsOf: pathWithFileName,encoding: .utf8).data(using: .utf8)!
var data = periodValue.data(using: .utf8)!
fileHandle.write(data)
fileHandle.closeFile()
} catch {
print("Error writing to file \(error)")
}
Here is a Swift 4 version as an extension to String.
extension String {
func writeToFile(fileName: String) {
guard let dir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else {
return
}
let fileUrl = dir.appendingPathComponent(fileName)
guard let data = self.data(using: .utf8) else {
return
}
guard FileManager.default.fileExists(atPath: fileUrl.path) else {
try? data.write(to: fileUrl, options: .atomic)
return
}
if let fileHandle = try? FileHandle(forUpdating: fileUrl) {
fileHandle.seekToEndOfFile()
fileHandle.write(data)
fileHandle.closeFile()
}
}
}