【问题标题】:App rejected due to downloading of image from server iOS应用程序因从服务器 iOS 下载图像而被拒绝
【发布时间】:2013-11-04 07:31:21
【问题描述】:

我开发了一个应用程序,我在其中从服务器下载图像并显示在UITableView

应用拒绝原因

特别是,我们发现在启动和/或内容下载时,您的应用存储 2.67 MB。要检查您的应用存储了多少数据:

iOS 数据存储指南指出,只有用户使用您的应用创建的内容,例如文档、新文件、编辑等,才应由 iCloud 备份。

您的应用程序使用的临时文件应仅存储在 /tmp 目录中;请记住在用户退出应用时删除存储在此位置的文件。

可以重新创建但必须保留以使您的应用正常运行的数据 - 或者因为客户希望它可以离线使用 - 应使用“不备份”属性进行标记。对于 NSURL 对象,添加 NSURLIsExcludedFromBackupKey 属性以防止相应文件被备份。对于 CFURLRef 对象,使用相应的 kCFURLIsExcludedFromBackupKey 属性。

这是我的代码,显示了我如何从服务器下载数据并显示它:

- (BOOL)fileExist:(NSString *)name  //Check's whether image Exists in Doc Dir.
{
    BOOL theSuccess;

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    theSuccess = [fileManager fileExistsAtPath:fullPath];
    if(theSuccess){
        return YES;
    } else {
        return NO;
    }
}

- (void)downloadFile:(NSString *)urlFile withName:(NSString *)fileName //If image not exists it will download image.
{
    NSString *trimmedString = [urlFile stringByTrimmingCharactersInSet:
                               [NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([trimmedString length]>0)
    {
        HTTPEaterResponse *response = [HTTPEater get:[NSString stringWithFormat:@"%@",trimmedString]];

        if ([response isSuccessful])
        {
            [self saveImage:[[UIImage alloc] initWithData:[response body]] withName:fileName];
        }
    }

}

-(void)saveImage:(UIImage *)image withName:(NSString *)name //After downloading image it stores in Doc dir.
{
    NSString  *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:[@"Documents/" stringByAppendingString:name]];
    [UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES];
}

- (UIImage *)loadImage:(NSString *)name //Used for displaying. 
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name];
    UIImage *img = [UIImage imageWithContentsOfFile:fullPath];

    return img;
}

显示数据的代码:

   - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
   {
       ...


    if ([dicImages valueForKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"merchantimage"]])
    {
        cell.MerchntLogo.image=[dicImages valueForKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"merchantimage"]];
    }
    else
    {
        if (!isDragging_msg && !isDecliring_msg)
        {
            if ([[[msg_array objectAtIndex:indexPath.row] valueForKey:@"merchantimage"] length]!=0)
            {
              [dicImages setObject:[UIImage imageNamed:@"rowDefault.png"] forKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"merchantimage"]];
              [self performSelectorInBackground:@selector(downloadImage_3:) withObject:indexPath];
            }
        }
        else
        {
            cell.MerchntLogo.image=[UIImage imageNamed:@"rowDefault.png"];
        }
    }

...

}

-(void)downloadImage_3:(NSIndexPath *)path{

    if ([[[msg_array objectAtIndex:path.row] valueForKey:@"merchantimage"] length]!=0)
    {
        NSString *str=[[msg_array objectAtIndex:path.row] valueForKey:@"merchantimage"];

        UIImage *img = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:str]]];
            [dicImages setObject:img forKey:[[msg_array objectAtIndex:path.row] valueForKey:@"merchantimage"]];

        [tblProdDetail performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
    }

}

请帮助我找出我的应用被拒绝的原因,以及我可以采取哪些措施来解决问题。

【问题讨论】:

    标签: ios iphone ipad uitableview uiimage


    【解决方案1】:

    您的应用明显违反了 Apple 的数据存储准则,该准则规定只有 用户生成的数据 应存储在 Documents 文件夹中。这些数据会自动备份到 iCloud 并违反 5GB 上限。如果某个应用在此文件夹中存储了太多数据(Apple 认为),那么它可能会被 App Store 拒绝。

    您的数据不会归类为用户生成的内容,并且超过了 2 MB 的限制。

    参考这里可以防止数据被备份。

    https://developer.apple.com/library/ios/qa/qa1719/_index.html

       - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
        {
            const char* filePath = [[URL path] fileSystemRepresentation];
    
            const char* attrName = "com.apple.MobileBackup";
            u_int8_t attrValue = 1;
    
            BOOL result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
            return result;
        }
    

    【讨论】:

      【解决方案2】:

      您需要按照他们所说的去做。标记文件

      只需添加 didFinishLaunching

      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
      documentsDirectory = [paths objectAtIndex:0];
      
      [self applyAttributes:documentsDirectory];
      

      然后实现这个方法

      #pragma mark - Application's Documents directory
      
      // Returns the URL to the application's Documents directory.
      - (NSURL *)applicationDocumentsDirectory
      {
      
      
          return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
       }
      
       -(void)applyAttributes:(NSString *)folderPath
       {
           NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil];
           NSEnumerator *filesEnumerator = [filesArray objectEnumerator];
           NSString *fileName;
      
           while (fileName = [filesEnumerator nextObject]) {
         // NSLog(@"apply to %@", [[NSURL fileURLWithPath:[folderPath stringByAppendingPathComponent:fileName]] path]);
          if([self addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:[folderPath stringByAppendingPathComponent:fileName]]])
          {
              //NSLog(@"success applying");
          }
      
          //NSDictionary *fileDictionary = [[NSFileManager defaultManager] attributesOfItemAtPath:[folderPath stringByAppendingPathComponent:fileName] error:nil];
          //fileSize += [fileDictionary fileSize];
        }
      
      }
      
      
      
      - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
      {
         if([[NSFileManager defaultManager] fileExistsAtPath: [URL path]])
         {
          NSError *error = nil;
          BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
                                        forKey: NSURLIsExcludedFromBackupKey error: &error];
          if(!success){
              NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
          }
          return success;
         }
      
         return NO;
      
      }
      

      【讨论】:

      • 我应该从哪里调用这个方法? - (NSURL *)applicationDocumentsDirectory
      【解决方案3】:

      使用此方法绕过在 iCloud 上存储数据

      将文件路径传递给该方法

          - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
          {
              const char* filePath = [[URL path] fileSystemRepresentation];
      
              const char* attrName = "com.apple.MobileBackup";
              u_int8_t attrValue = 1;
      
              BOOL result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
              return result;
          }
      

      【讨论】:

      • 我应该从哪里调用这个方法?我应该保持原样吗? const char* attrName = "com.apple.MobileBackup";
      • 在将文件保存到本地目录之后..我还建议您创建自己的目录来下载和保存图像...使用此方法创建目录 if (![[NSFileManager defaultManager] createDirectoryAtPath :filePathAndDirectory withIntermediateDirectories:NO attributes:nil error:&error]) { NSLog(@"创建目录错误:%@", error); }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-04
      • 2018-01-25
      • 1970-01-01
      • 2012-11-07
      • 2012-08-30
      • 2016-12-06
      • 1970-01-01
      相关资源
      最近更新 更多