从委托传递给数据模型的字符串导致具有委托类的对象

时间:2014-05-27 22:51:30

标签: ios objective-c nsurlconnection nsurl

我对objective-c很新,并且我的一些代码存在问题,而我无法在SO或其他地方找到解决方案。感谢您的耐心等待。

基本上,我有一个访问我服务器数据的模型类,以及两个视图控制器,它们在模型的不同实例上充当代理,每个视图控制器都被分配为一个委托。

第一个视图控制器(ListViewController)只包含一个列表,数据加载正常。

第二个视图控制器(MapViewController)只包含一个地图。这就是问题所在:

我在视图控制器的viewDidLoad方法中创建一个URL作为NSString,并将其传递给该视图控制器使用的模型实例。在模型中,urlString随后转换为NSURL,并启动连接/数据集合。没有数据从模型返回。

经过一些调试后,我发现传入模型下载的urlString会将它的类保留为字符串,但jsonFileUrl变量将具有MapViewController类,而不是NSURL。

以下是我的一些代码。

DataModel.h

#import <Foundation/Foundation.h>

@protocol DataModelProtocol <NSObject>

- (void)itemsDownloaded:(NSArray *)items;

@end

@interface DataModel : NSObject <NSURLConnectionDataDelegate>

@property (weak, nonatomic) id<DataModelProtocol> delegate;

- (void)downloadItems:(NSString *)urlString;

@end

DataModel.m

#import "DataModel.h"
#import "CustomClass.h"

@interface DataModel() {
    NSMutableData *_downloadedData;
}

@end

@implementation DataModel

- (void)downloadItems:(NSString *)urlString {

    //create url object with the link to download the json data
    //    THIS IS WHERE THE JSONFILEURL ENDS UP BECOMING MAPVIEWCONTROLLER CLASS
    NSURL *jsonFileUrl = [NSURL URLWithString:urlString];

    //create the url request
    NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];

    //create connection to the url
    [NSURLConnection connectionWithRequest:urlRequest delegate:self];
}

... //functions to receive and parse results...

ListViewController.h

#import <UIKit/UIKit.h>
#import "DataModel.h"

@interface ListViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, DataModelProtocol>

@property (weak, nonatomic) IBOutlet UITableView *listOneTableView;
@property (weak, nonatomic) NSString *var1;
@property (weak, nonatomic) NSString *var2;

@end

ListViewController.m

#import "ListViewController.h"
#import "MapViewController.h"
#import "DataModel.h"
#import "CustomClass.h"

@interface ListViewController () {
    DataModel *_dataModelInstance1; //data model to retrieve provider types
    NSArray *_feedItems; //array for provider types
    CustomClass *_selectedCustomInstance;
}

@end

@implementation ListViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    //set this view controller as the delegate and data source for the table view
    self.listOneTableView.delegate = self;
    self.listOneTableView.dataSource = self;

    //initialize an array object assigned to the pointer _feedItems
    _feedItems = [[NSArray alloc] init];

    //create a new data model and assign it to _providerTypeDataModel
    _dataModelInstance1 = [[DataModel alloc] init];

    //set this view controller as the delegate for the _providerTypeDataModel object
    _dataModelInstance1.delegate = self;

    //call the downloadItems method of the _providerTypeDataModel object
    //  this will have the model download the data and organize it for us. afterwards, we need to handle it through the itemsDownloaded function
    NSString *downloadURL = [NSString stringWithFormat:@"http://www....com/phpfile.php?var1=%@&var2=%@", self.var1, self.var2];

    [_dataModelInstance1 downloadItems:downloadURL]; //THIS ONE WORKS FINE
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)itemsDownloaded:(NSArray *)items {

    _feedItems = items;
    [self.listOneTableView reloadData];
}

...//delegate methods and segue to MapViewController which passes var1, var2, and _selectedCustomInstance

MapViewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "DataModel.h"
#import "CustomClass.h"

@interface MapViewController : UIViewController <DataModelProtocol>


@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (weak, nonatomic) NSString *var1;
@property (weak, nonatomic) NSString *var2;
@property (weak, nonatomic) NSString *selectedCustomInstance;

@end

MapViewController.m

#import "MapViewController.h"
#import "DataModel.h"
#import "CustomClass.h"

@interface MapViewController () {
    DataModel *_dataModelInstance2;
    NSArray *_returnedArray;
}

@end

@implementation MapViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    //initialize array for the provider list
    _returnedArray = [[NSArray alloc] init];

    //create new datamodel for the provider list
    _dataModelInstance2 = [[DataModel alloc] init];

    //set this view controller as the delegate for the datamodel object
    _dataModelInstance2.delegate = self;

    //THIS STRING IS CREATED ACCURATELY, AND WHEN TESTED INDEPENDENTLY IN THE BROWSER, RETURNS THE DESIRED JSON
    NSString *downloadURL = [NSString stringWithFormat:@"http://www.....com/phpfile2.php?var1=%@&var2=%@&var3=%@", self.var1, self.var2, self.selectedCustomInstance];

    //THIS MODEL METHOD GETS CALLED, AND THE NSSTRING IS PASSED, BUT SUBSEQUENT CONVERSION TO NSURL RESULTS INSTEAD IN A MODELVIEWCONTROLLER CLASS OBJECT
    [_dataModelInstance2 downloadItems:downloadURL];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)itemsDownloaded:(NSArray *)items {
    _returnedArray = items;
}

@end

1 个答案:

答案 0 :(得分:0)

这是一种猜测,因为我们有不完整的信息,但似乎它工作的实例和它不起作用的实例之间的唯一区别是URL的实际形式。这让我相信这是一个编码问题,因为你没有编码你的字符串。

尝试添加以下行作为downloadItems:(NSString *)urlString;的第一行:

urlString = [urlString sstringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];