Swift iOS 앱을 사용하여 많은 파일을 다운로드 중이며 내용을 점진적으로 업데이트합니다.Swift - 파일 이동 또는 업데이트가 실패합니다.
, 내가, 파일 또는 폴더가 대상 디렉토리에 존재하는 경우가 확인 압축 해제, 임시 디렉토리에 Alamofire을 사용하여 파일을 다운로드가 발견되면 제거하고 새 파일을 이동 내 다운로드 코드는 아주 기본입니다/해당 디렉토리의 폴더에 있습니다.
그러나 기존 디렉토리를 확인하고 제거한 후에는 거의 문제가 없습니다. 내가 그 디렉토리에 새 파일/폴더을 이동하려고 할 때, 나는
의 오류 "파일 또는 디렉토리가 이미 존재하거나 내용이 비어 있지 않습니다."
그러나 장치 디렉토리에서 오류가 발생했는지 확인했지만 완전히 정밀한 디렉토리가 표시되거나 충돌 할 수있는 기존 파일이 없거나 새로운 내용이 대상 디렉토리로 옮겨지는 경우도 있습니다 그것은 실패했다. 그것이 나를 가장 괴롭히는 것입니다.
디렉토리에 파일을 저장하고 이동할 때 이런 종류의 동작을 경험 한 적이 있습니까?
나는 거의 깜빡하고 있는데, 나는 애플리케이션 지원 디렉토리에서 일하고있다.
internal func loadArtifact(artifact: Artifact, updateClosure: @escaping ((Bool, Int64, Int64, String?) ->()))
{
let serverpath = artifact.serverpath
let name = artifact.name
let zipname = artifact.zipname
let root = artifact.artifactSetroot
let hidden = artifact.artifactSet!.hidden
let objectID = artifact.objectID
let baseArtifactSet = artifactSetManager.defaultartifactSetManager.getartifactSetDirectory(artifact.artifactSet!)
if baseArtifactSet == nil
{
errorLog("No target directory for artifactSet")
return
}
if name == nil
{
errorLog("No name for artifact. Can´t save in temp")
return
}
var targetDirectory = baseArtifactSet
targetDirectory?.appendPathComponent("temp")
targetDirectory?.appendPathComponent(zipname!.replacingOccurrences(of: ".zip", with: ""))
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
return (targetDirectory!, [.removePreviousFile, .createIntermediateDirectories])
}
let url = URL(string: serverpath!)
alamofireManager!.download(url!, to: destination).downloadProgress { (progress) in
updateClosure(false, progress.completedUnitCount, progress.completedUnitCount, nil)
}.responseData { (data) in
traceLog("\(data)")
if data.response?.statusCode == 200
{
traceLog("Got an artifact. Will continue to extract itto target position")
self.asyncQueue.async {
var unzipTarget = baseArtifactSet
SSZipArchive.unzipFile(atPath: targetDirectory!.path, toDestination: root ? "\(unzipTarget!.path)/temp/root" : "\(unzipTarget!.path)/temp", progressHandler: { (message, something, progress, max) in
}, completionHandler: { (message, finished, error) in
let tmpPath = root ? "\(unzipTarget!.path)/temp/root" : "\(unzipTarget!.path)/temp/artifacts/\(zipname!.replacingOccurrences(of: ".zip", with: ""))"
let targetPath = root ? unzipTarget!.path : "\(unzipTarget!.path)/artifacts/\(zipname!.replacingOccurrences(of: ".zip", with: ""))"
if error == nil && root == false && FileManager.default.fileExists(atPath: targetPath)
{
do
{
try FileManager.default.removeItem(atPath: targetPath)
traceLog("Deletet old directory at path: \(unzipTarget!.path)")
}catch
{
errorLog("Could not remove directory at path: \(unzipTarget!.path) - \(error)")
updateClosure(true,0,0,"Could not remove directory at path: \(unzipTarget!.path) - \(error)")
}
}
do
{
if FileManager.default.fileExists(atPath: "\(unzipTarget!.path)/artifacts") == false
{
try FileManager.default.createDirectory(atPath: "\(unzipTarget!.path)/artifacts", withIntermediateDirectories: true, attributes: nil)
}
if root
{
do{
let targetDirContent = try FileManager.default.contentsOfDirectory(atPath: targetPath)
for file in targetDirContent
{
if file != "artifacts" && file != "temp"
{
try FileManager.default.removeItem(atPath: "\(targetPath)/\(file)")
}
}
let files = try FileManager.default.contentsOfDirectory(atPath: tmpPath)
for file in files
{
let fileURL = URL(fileURLWithPath: "\(tmpPath)/\(file)")
if fileURL != nil
{
try FileManager.default.moveItem(atPath: fileURL.path, toPath: "\(targetPath)/\(file)")
}
}
if root && hidden
{
let deviceInfoString = "var deviceInfo={'platform':'iOS'}"
if FileManager.default.fileExists(atPath: "\(targetPath)/deviceInfo.js")
{
try FileManager.default.removeItem(atPath: "\(targetPath)/deviceInfo.js")
}
}
}
catch{
errorLog("Error while enumerating files in temp root directory: \(error)")
updateClosure(true,0,0,"Error while enumerating files in temp root directory: \(error)")
}
}else
{
if FileManager.default.fileExists(atPath: targetPath)
{
debugLog("Deleting: \(targetPath)")
try FileManager.default.removeItem(atPath: targetPath)
}else
{
debugLog("Creating: \(targetPath)")
}
debugLog("Trying to move")
try FileManager.default.moveItem(atPath: tmpPath, toPath: targetPath)
}
}catch
{
errorLog("Could not move directory for artifact: \(unzipTarget!.path) - \(error)")
updateClosure(true,0,0,"Could not move directory for artifact: \(unzipTarget!.path) - \(error)")
}
try FileManager.default.removeItem(atPath: targetDirectory!.path)
self.asyncQueue.async (flags: .barrier) {
let ownContext = MyStorageClient.defaultManager.newBackgroundWorkerMOC()
let ownArtifact = ownContext.object(with: objectID) as! Artifact
ownArtifact.state = ArtifactState.Ready.rawValue
ownArtifact.updateAvaiable = false
if root == true && ownArtifact.artifactSet?.state == artifactSetState.Initialised.rawValue
{
ownArtifact.artifactSet?.state = artifactSetState.Created.rawValue
}
do{
try ownContext.save()
updateClosure(true, 0,0,nil)
}catch{
errorLog("Error while saving artifact context")
updateClosure(true, 0,0, "Error while saving context after artifact Update. \(error)")
}
}
})
}
}else
{
errorLog("Something went wrong downloading an artifact: \(data.response)")
updateClosure(true,0,0,"Something went wrong downloading an artifact: \(data.response)")
}
}
}
아무에게도 왜 실패하고 있는지 말할 수 있습니까? 나는 시도 라인의 대부분의 주위에 - - 캐치를 시도 할 추가, 그것이 실패했을 때, 그것은 기본적으로이 덩어리에 실패 :
if FileManager.default.fileExists(atPath: targetPath)
{
debugLog("Deleting: \(targetPath)")
try FileManager.default.removeItem(atPath: targetPath)
}else
{
debugLog("Creating: \(targetPath)")
}
debugLog("Trying to move")
try FileManager.default.moveItem(atPath: tmpPath, toPath: targetPath)
있는 TargetPath은 다음과 같습니다 파일 : /// VAR/모바일/용기/데이터/응용 프로그램/applicationIdAndStuff/라이브러리/응용 프로그램 % 20Support/환경/작업 공간/고객/고객/온도/downloadFileOrFolder
또 다른 갱신 : 나는 코드를 변경, 그래서 이전 파일은 백업 폴더로 이동하는 대신 삭제됩니다 바로 주소를 변경하는 것이 파일을 완전히 삭제하는 것보다 빠르다고 생각했기 때문입니다. 잘못된. 이제 오류는 이전보다 더 자주 발생합니다.
나를 위해 문제는 FileManager를 참조하므로 절차를 완료하는 데 너무 오래 걸립니다. 나는 정말로 내 블록을 언제든지 잠자기하고 싶지 않습니다. 어떻게이 문제를 해결할 수 있는지에 대한 아이디어가 있습니까?
코드를 작게 만들 수 있습니까? 나는 그 모든 것을 읽기에는 너무 게으름입니다. – zombie
전체 코드 맨 위에 문제가있는 부분 아래에 업데이트되었습니다. –
@Viktor_DE, 런타임에서'targetPath'의 값은 무엇입니까? – holex