2016-03-04 20 views
-4

我知道这是一个愚蠢的问题,但我找不到解决方案。

这里是我的代码:
ConnectionService.h
试图从异步调用传输数据到另一个类

#import "LaunchScreenViewController.h" 
@interface ConnectionService : NSObject 

-(void)getsFeaturedProducts; 

@end 

ConnectionService.m

-(void)getsFeaturedProducts { 
NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]]; 
    NSURL *url = [NSURL URLWithString:urlString]; 

    NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){ 
     NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
     NSDictionary *value = [rawJson JSONValue]; 
     _featuredProducts = [[NSDictionary alloc]initWithDictionary:value]; 
     NSLog(@"Featured products: %@", _featuredProducts);//not empty 

     LaunchScreenViewController *lsvc = [[LaunchScreenViewController alloc]init]; 
     lsvc.featuredProducts = self.featuredProducts; 
NSLog(@"Featured products: %@", lsvc.featuredProducts);//not empty 
    }]; 
    [getData resume]; 
} 

LaunchScreenViewController.h

#import "ConnectionService.h" 

@interface LaunchScreenViewController : UIViewController 
@property(nonatomic,strong) NSDictionary *featuredProducts; 
@end 

LaunchScreenViewController.m

- (void)viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:YES]; 

    ConnectionService *connectionService = [[ConnectionService alloc]init]; 
    [connectionService refreshProducts]; 

    self.featuredProducts = [[NSDictionary alloc]init]; 
    NSLog(@"featuredProducts: %@", self.featuredProducts);//empty 
    NSArray *keys = [[NSArray alloc]initWithArray:[self.featuredProducts allKeys]]; 
    NSLog(@"All featured product keys: %@", keys); 
} 

我做错了什么?

P.S.编程objective-c少于一个月,所以是的...谢谢你的-rep。

+0

'[[洗衣机。 chScreenViewController alloc] init]'创建一个新的对象。然后你更新它的属性,但是你永远不会呈现它,所以这个对象的视图永远不会出现。如果您已在屏幕上显示'LaunchScreenViewController',则需要使用它。 –

+0

这是我第一次建议,但它没有奏效。 – Ookey

回答

0

你的代码不起作用,因为用alloc init创建的LaunchScreenViewController实例不是在Storyboard/XIB文件中创建的实例。


从另一个类异步检索数据的推荐方法是完成处理程序。

ConnectionService.m使用完成处理程序实现该方法并在.h文件中相应地声明它。

- (void)getsFeaturedProductsWithCompletion:(void (^)(NSDictionary *products))completion 
{ 
    NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]]; 
    NSURL *url = [NSURL URLWithString:urlString]; 

    NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){ 
    NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
    NSDictionary *value = [rawJson JSONValue]; 
    completion(value); 
    }]; 
    [getData resume]; 
} 

备注:强烈建议在数据任务中添加错误处理!


LaunchScreenViewController.h声明为ConnectionService实例

#import "ConnectionService.h" 

@interface LaunchScreenViewController : UIViewController 
@property(nonatomic,strong) NSDictionary *featuredProducts; 
@property(nonatomic,strong) ConnectionService *connectionService; 
@end 

一个属性在LaunchScreenViewController.m呼叫的方法

- (void)viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:YES]; 

    connectionService = [[ConnectionService alloc]init]; 
    [connectionService getsFeaturedProductsWithCompletion:^(NSDictionary *products) { 
    self.featuredProducts = products; 
    NSLog(@"featuredProducts: %@", self.featuredProducts);//empty 
    NSArray *keys = [[NSArray alloc]initWithArray:[self.featuredProducts allKeys]]; 
    NSLog(@"All featured product keys: %@", keys); 
    connectionService = nil; // release the connectionService instance if needed 
    }]; 
} 
0

您需要将结果返回给您的控制器。

你需要做的是给你的 - (void)getsFeaturedProducts函数添加一个完成块,然后一旦结果返回,你就调用它传回结果。

在同一功能中,您可以使用正确的数据重新加载视图。

服务

-(void)getsFeaturedProducts:(void (^)(NSDictionary *featuredProducts))completionHandler { 
     NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]]; 
NSURL *url = [NSURL URLWithString:urlString]; 

     NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){ 
      NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
      NSDictionary *featuredProducts = [rawJson JSONValue]; 
      completionHandler(featuredProducts); 
     }]; 
    [getData resume]; 
} 

控制器

- (void)viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:YES]; 

    ConnectionService *connectionService = [[ConnectionService alloc]init]; 
    [connectionService refreshProducts:^(NSDictionary *featuredProducts) { 
     self.featuredProducts = featuredProducts; 
     NSLog(@"featuredProducts: %@", self.featuredProducts); 
     NSArray *keys = [[NSArray alloc]initWithArray:[self.featuredProducts allKeys]]; 
     NSLog(@"All featured product keys: %@", keys); 

     //Reload data here... 
}]; 

}

+0

我不按任何控制器,LaunchScreenViewController是我的应用程序启动时显示的第一个ViewController。 – Ookey

+0

不适当回复...等待:) – mt81

+0

这个答案有可能成为最习惯和最简洁的解决方案。但是,@ mt81,请添加更多代码。 ;) – CouchDeveloper

-1
-(void)getsFeaturedProducts { 
NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]]; 
NSURL *url = [NSURL URLWithString:urlString]; 
NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
     NSDictionary *value = [rawJson JSONValue]; 
     _featuredProducts = [[NSDictionary alloc]initWithDictionary:value]; 
     NSLog(@"Featured products: %@", _featuredProducts);//not empty 

     LaunchScreenViewController *lsvc = [[LaunchScreenViewController alloc]init]; 
     lsvc.featuredProducts = self.featuredProducts; 
     [[[UIApplication sharedApplication] keyWindow] setRootViewController:lsvc]; 
    }) 

}]; 
[getData resume]; 
} 
+0

我使用UI的故事板,所以我不使用segues。但是这个'[[[UIApplication sharedApplication] keyWindow] setRootViewController:lsvc];'不会改变任何东西。 – Ookey

+0

我想将'NSObjec'转换成'ViewController',而不是'ViewController-> ViewController' – Ookey

+0

它的一个难题! –

1

你在想这个同步的问题错了 - 但你并不远关闭。以下是您的代码现在正在执行的操作:

  1. LaunchScreenViewController的实例已创建。

  2. 这LaunchScreenViewController的实例创建ConnectionService实例

  3. 为您的异步数据ConnectionService查询

  4. 当返回数据,它创建LaunchScreenViewController的全新实例,并通过它的数据。

  5. 您检查数据的原始LaunchScreenViewController,但没有任何 - 它进入新的实例。

您想要将数据传回原始的LaunchScreenViewController。有几种方法可以做到这一点。我会告诉你一个,并链接到第二个。

让我们做如何通过NSNotificationCenter数据传回给原来的控制器的例子:

LaunchScreenViewController.m

- (void)viewDidLoad:(BOOL)animated{ 
    //Your current code.... 

    [[NSNotificationCenter defaultCenter] addObserver:self 
    selector:@selector(receiveConnectionData:) 
    name:@"ConnectionDataReceived" 
    object:nil]; 

} 

- (void) receiveTestNotification:(NSNotification *) notification 
{ 
    // [notification name] should always be @"ConnectionDataReceived" 
    // unless you use this method for observation of other notifications 
    // as well. 

    if ([[notification name] isEqualToString:@"ConnectionDataReceived"]){ 

     self.featuredProducts = [[NSDictionary alloc]init]; 
     NSLog(@"featuredProducts: %@", self.featuredProducts);//empty 
     NSArray * 
     NSArray *keys = [[NSArray alloc]initWithArray:[notification.object allKeys]]; 
     NSLog(@"All featured product keys: %@", keys); 
     NSLog (@"Successfully received the test notification!"); 
    } 
} 

在你ConnectionService.h

-(void)getsFeaturedProducts { 
    NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]]; 
    NSURL *url = [NSURL URLWithString:urlString]; 

    NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){ 
     NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
     NSDictionary *value = [rawJson JSONValue]; 
     _featuredProducts = [[NSDictionary alloc]initWithDictionary:value]; 
     NSLog(@"Featured products: %@", _featuredProducts);//not empty 

     //Pass the NSDictionary back to the ORIGINAL LaunchViewController 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"ConnectionDataReceived" _featuredProducts]; 
}]; 
[getData resume]; 

}

注意:您也可以使用委托来完成此任务,这更复杂但更强大。你可以在这里找到Chris Mills的一个很好的教程:https://coderchrismills.wordpress.com/2011/05/05/basic-delegate-example/

+0

谢谢,它的帮助! – Ookey

相关问题