我发布了我的应用程序以便在Applestore中进行审核,我得到了拒绝,其中说:
" 在启动和内容下载时,您的应用会在用户的iCloud上存储1.4 GB,这不符合iOS数据存储指南。 "
我在问题的最后粘贴了完整的拒绝文本。
我不知道将数据存储到ICLoud,我不确定他们如何测试我的应用程序。他们建议查看ICloud存储的设置,我已经完成了什么,但在安装时我无法看到我的应用使用的任何ICloud存储:
是否有任何自动过程在一段时间或设置后将数据从文档文件夹存储到云中?
通常我的应用是 - 从我的服务器下载zipfile以存储在我的应用程序的Document文件夹中。 - 然后应用程序也在文档文件夹中解压缩zipfile。
使用IOS-Simulator进行测试时,我可以使用shell检查文档文件夹的内容,内容就在那里。 (而不是在ICloud上)
有人可以帮助我,开发人员在这种情况下必须做些什么。
我在此处粘贴了相关代码,其中显示了我如何下载内容以及如何解压缩内容。
class ViewController: UIViewController, NSURLSessionDelegate {
let sDataPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString as String; ///var/mobile/Containers/Data/Application/8897ED62-5BAE-4255-8459-F0F8381C171F/Documents/
download_file(sfrom,sToLocation: sDataPath);
func download_file(sURL: String, sToLocation: String) {
print("start downloading ...");
print("sURL : " + sURL + " sToLocation : " + sToLocation);
bytesDownloaded=0;
let downloadsessiondelegate = self;
downloadsessiondelegate.storePath=sToLocation;
downloadsessiondelegate.progressView=progressView;
downloadsessiondelegate.surl=sURL;
struct SessionProperties {
static let identifier : String! = "url_session_background_download"
}
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Hour, .Minute], fromDate: date)
let hour = String(components.hour)
let minutes = String(components.minute)
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("session_" + hour + minutes)
let backgroundSession = NSURLSession(configuration: configuration, delegate: downloadsessiondelegate, delegateQueue: nil)
//myURLSession = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
let url = NSURLRequest(URL: NSURL(string: sURL)!)
//var downloadTask = backgroundSession.downloadTaskWithRequest(url)
let downloadTask = backgroundSession.downloadTaskWithRequest(url)
downloadTask.resume()
}
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location1: NSURL) {
//println("session \(session) has finished the download task \(downloadTask) of URL \(location1).")
// remove Session ID
//defaults.removeObjectForKey(<#defaultName: String#>)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.removeObjectForKey("SessionProperties_identifier" + "_" + surl)
var error: NSError?
let target=storePath;
var source : String = location1.absoluteString;
let filemgr = NSFileManager.defaultManager();
let modifiedsource = source.stringByReplacingOccurrencesOfString("file://", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
if (filemgr.fileExistsAtPath(target))
{
do {
try filemgr.removeItemAtPath(target)
} catch let error1 as NSError {
error = error1
}
//println("FILE AVAILABLE");
}
do {
try filemgr.moveItemAtPath(modifiedsource, toPath: target)
dispatch_async(dispatch_get_main_queue(),{
self.progressView.setProgress(0, animated: false);
//progressView.removeFromSuperview();
print("Move successful")
self.install_content();
})
//download_file_finished();
} catch var error1 as NSError {
error = error1
print("Moved failed with error: \(error!.localizedDescription)")
install_failed("Moved failed with error: \(error!.localizedDescription)");
}
}
func unzipFile(sZipFile: String, toDest: String, estimatedByte:Int){
SSZipArchive.unzipFileAtPath(sZipFile, toDestination: toDest, progressHandler: {
(entry, zipInfo, readByte, totalByte) -> Void in
//let itotalByte=totalByte;
let stufe=4096*1000;
if totalByte % stufe == 0 {
//println("readByte : \(totalByte)")
}
dispatch_async(dispatch_get_main_queue()) {
var percent:Float=Float(Float(totalByte)/Float(estimatedByte));
if percent>1.0{
percent=1.0;
}
let percent_int=Int(percent*100);
let percenttext:String=String(percent_int);
self.progressView.setProgress(percent, animated: false);
let sMessage=self.actualinstalldefinition.title;
let messagewithprozent=sMessage + " (" + percenttext + "%)";
self.progress_label_Titel.text = messagewithprozent;
if percent_int % 20 == 0 && self.lastpercent != percent_int{
let progressimage=self.get_random_progress_image();
self.progressImageView.image = progressimage;
self.lastpercent=percent_int;
}
}
}, completionHandler: { (path, success, error) -> Void in
if success {
// Loesche das ZipFile
let fileManager = NSFileManager.defaultManager()
var error: NSError?
if (fileManager.fileExistsAtPath(sZipFile)){
do {
try fileManager.removeItemAtPath(sZipFile)
} catch let error1 as NSError {
error = error1
} catch {
fatalError()
}
}
dispatch_async(dispatch_get_main_queue(),{
self.progressView.setProgress(0, animated: false);
//progressView.removeFromSuperview();
print("Move successful")
self.install_content();
})
} else {
//progressBar?.hidden = true
self.install_failed(error.localizedDescription);
print(error)
}
})
}
完整拒绝声明:
2.23 - Apps must follow the iOS Data Storage Guidelines or they will be rejected
2.23详细信息
在启动和内容下载时,您的应用会在用户的iCloud上存储1.4 GB,这不符合iOS数据存储指南。
后续步骤
请确认iCloud仅根据iOS数据存储指南的要求备份用户使用您的应用创建的内容,例如文档,新文件,编辑等。另外,检查应用程序使用的任何临时文件是否只存储在/ tmp目录中;请记住,在确定不再需要这些文件时,请删除或删除存储在此位置的文件。
可以重新创建但必须保持应用程序正常运行的数据 - 或者因为用户希望它可供离线使用 - 应标记为&#34;不要备份&#34;属性。对于NSURL对象,请添加NSURLIsExcludedFromBackupKey属性以防止备份相应的文件。对于CFURLRef对象,请使用相应的kCRUFLIsExcludedFromBackupKey属性。
资源
要检查应用存储的数据量:
- Install and launch your app
- Go to Settings > iCloud > Storage > Manage Storage
- Select your device
- If necessary, tap "Show all apps"
- Check your app's storage
有关防止文件备份到iCloud和iTunes的其他信息,请参阅技术问答1719:如何防止文件备份到iCloud和iTunes。
如果您在复制报告的问题时遇到困难,请尝试测试技术Q&amp; A QA1764:如何重现针对App Store提交的错误报告中描述的工作流程。
如果您在使用上述资源后遇到代码级问题,则可以咨询Apple Developer技术支持。当DTS工程师跟进您时,请准备好提供: - 拒绝问题的完整详情 - 截图 - 重现问题的步骤 - 符号化的崩溃日志 - 如果您的问题导致崩溃日志
答案 0 :(得分:4)
放置在Documents文件夹中的文件会自动备份到iCloud。
备份过程可能无法立即启动,这就是您没有看到应用的iCloud存储空间的原因。
使用此代码从自动备份中排除文件。
try! filePath.setResourceValue(true, forKey: NSURLIsExcludedFromBackupKey)
有关详细信息,请参阅docs。