0

可能是我的问题看起来很奇怪,但是......(希望有人帮助我)

有两种方法可以从 FTP 加载一些数据。有时应用程序挂在这些方法上。

  1. 检查互联网连接。
  2. 如果互联网可用:

    @interface Download : NSObject {
        NSOperationQueue *operationQueue;
    }
    
    ...
    
    if (!operationQueue) {
        operationQueue = [NSOperationQueue new];
    }
    
    NSInvocationOperation *operation1;
    operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadIngredientsFromJSON) object:nil];
    [operationQueue addOperation:operation1];
    
    NSInvocationOperation *operation2;
    operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadRecipesFromJSON) object:nil];
    [operation2 addDependency:operation1];
    [operationQueue addOperation:operation2];
    
    [operationQueue addObserver:self forKeyPath:@"operations" options:0 context:NULL];
    
  3. 方法loadIngredientsFromJSON & loadRecipesFromJSON

    -(void) loadIngredientsFromJSON
    {
        NSInteger countInBase = [self dataCountInEntity:@"Ingredients"];
    
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"ftp://...Ingredients.json"]];
        NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
        NSError *error = nil;
        if (!responseData) {
            return;
        }
    
        NSDictionary *ingredientsDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
        if (!ingredientsDictionary) {
           return;
        }
    
        //NSLog(@"%@", [ingredientsDictionary description]);
    
        NSArray *keys = [ingredientsDictionary allKeys];
        if (!countInBase && [ingredientsDictionary count]>0) {
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        for (int i=0; i<[ingredientsDictionary count]; i++) {
           id aKey = [keys objectAtIndex:i];
           NSArray *ingrData = [ingredientsDictionary objectForKey:[NSString stringWithFormat:@"%@", aKey]];
           NSArray *tmpArray = [NSArray arrayWithObjects:aKey, [ingrData objectAtIndex:0], [ingrData objectAtIndex:1], nil];
           Ingredients *ingredient = [NSEntityDescription insertNewObjectForEntityForName:@"Ingredients" inManagedObjectContext:appDelegate.managedObjectContext];
    
           ingredient.code = [NSNumber numberWithInteger:[[tmpArray objectAtIndex:0] integerValue]];
           ingredient.name = [tmpArray objectAtIndex:1];
           ingredient.units = [tmpArray objectAtIndex:2];
           ingredient.type = [NSNumber numberWithInt:1];
           [appDelegate.managedObjectContext save:nil];
        }
        }
    }
    

...

    - (void) loadRecipesFromJSON
    {        
       NSInteger missedCount = 0;
       NSInteger recipeCode = 0;
       NSString *recipesPath = @"ftp://...";

       do {
         recipeCode ++;
         NSString *recipeFileName = [NSString stringWithFormat:@"recipes/%05d.json", recipeCode];
         NSString *recipeFileFullPath = [recipesPath stringByAppendingString:recipeFileName];

         NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeFileFullPath]];
         NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
         NSError *error = nil;
         if (!responseData) {
            missedCount ++;
            continue;
         }
         NSDictionary *recipeDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
         if (!recipeDictionary) {
            missedCount ++;
            continue;
         }

         AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

         NSInteger recipeCount = [self isDataExistInEntity:@"Recipes" withCode:[[recipeDictionary objectForKey:@"recipeCode"] integerValue]];
    if (recipeCount == 0) {
        Recipes *recipe = [NSEntityDescription insertNewObjectForEntityForName:@"Recipes" inManagedObjectContext:appDelegate.managedObjectContext];
        recipe.code = [recipeDictionary objectForKey:@"recipeCode"];
        recipe.dateUpdated = [recipeDictionary objectForKey:@"dateEdited"];
        recipe.inCategory = [recipeDictionary objectForKey:@"inCategory"];
        recipe.name = [recipeDictionary objectForKey:@"recipe"];
        recipe.difficulty = [recipeDictionary objectForKey:@"difficulty"];
        recipe.personCount = [recipeDictionary objectForKey:@"personCount"];
        recipe.prepHour = [recipeDictionary objectForKey:@"prepHour"];
        recipe.prepMin = [recipeDictionary objectForKey:@"prepMin"];
        int seconds = ([recipe.prepMin intValue]*60)+([recipe.prepHour intValue] * 60 * 60);
        recipe.prepTime = [NSNumber numberWithInt: seconds];
        recipe.isPaid = [recipeDictionary objectForKey:@"isPaid"];
        recipe.comment = [recipeDictionary objectForKey:@"comments"];

        NSDictionary *ingredients = [recipeDictionary objectForKey:@"ingredients"];
        NSArray *keys = [ingredients allKeys];
        if ([keys count] > 0) {
            for (int i=0; i<[keys count]; i++) {
                Join *join = [NSEntityDescription insertNewObjectForEntityForName:@"Join" inManagedObjectContext:appDelegate.managedObjectContext];
                join.recipeCode = [recipeDictionary objectForKey:@"recipeCode"];

                id aKey = [keys objectAtIndex:i];
                join.ingredientCode = [NSNumber numberWithInteger:[aKey integerValue]];

                NSString *str = [ingredients objectForKey:aKey];
                double num = [str doubleValue];
                join.count = [NSNumber numberWithDouble:num];

                join.inCart = [NSNumber numberWithInt:0];
            }
        }

        NSDictionary *prepStages = [recipeDictionary objectForKey:@"prepStage"];
        keys = [prepStages allKeys];
        if ([keys count] > 0) {
            for (int i=0; i<[keys count]; i++) {
                PrepStages *prepStage = [NSEntityDescription insertNewObjectForEntityForName:@"PrepStages" inManagedObjectContext:appDelegate.managedObjectContext];
                prepStage.recipeCode = [recipeDictionary objectForKey:@"recipeCode"];

                id aKey = [keys objectAtIndex:i];
                prepStage.order = [NSNumber numberWithInteger:[aKey integerValue]];
                prepStage.descriptions = [prepStages objectForKey:aKey];

                //загрузка картинки
                NSString *recipeImageName = [NSString stringWithFormat:@"recipeImages/%05d-%@.jpg", recipeCode, [NSNumber numberWithInteger:[aKey integerValue]]];
                NSString *recipeImageFullPath = [recipesPath stringByAppendingString:recipeImageName];
                NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:recipeImageFullPath]];
                if (request) {
                    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

                    if (responseData) {
                        UIImage *image = [UIImage imageWithData:responseData];
                        prepStage.image = image;
                    }
                }

            }
        }
        [appDelegate.managedObjectContext save:nil];
    }
    else {
        missedCount ++;
        continue;
    }

    } while (missedCount < 10);
    }

有时在这两种方法之一中,应用程序挂起和控制冻结。

谁能给我一些建议,哪一行可能有错误。

我糊涂了...

已编辑

我注意到有趣的事情:

下载过程在应用程序运行时开始。它从服务器下载食谱并将它们插入到 CoreData。如果我点击查看我用来获取数据的食谱列表。当它想要插入数据时,appDelegate.managedObjectContextDownload 也会使用。appDelegate.managedObjectContext

这可以包含问题吗?

4

0 回答 0