I've been creating an app that is supposed to show Pins on a Map that are stored in a MySQL Database. I've used JavaScript to convert the Database to JSON then converted the JSON data into NSStrings.
The problem here is I then needed to convert two of these NSStrings into doubles because my Pins need to placed via latitude and longitude, here is my code below that when it builds shows no issues but crashes my simulator and shows up some errors which I shall post directly under my code.
Hazards.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface Hazards : NSObject <MKAnnotation>
#property (nonatomic, assign) CLLocationDegrees latitude;
#property (nonatomic, assign) CLLocationDegrees longitude;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#property (nonatomic, strong) NSString * ID;
#property (nonatomic, strong) NSString * ROUTE;
#property (nonatomic, strong) NSString * ADDRESS;
#property (nonatomic, strong) NSString * LATITUDE;
#property (nonatomic, strong) NSString * LONGITUDE;
#property (nonatomic, strong) NSString * HAZARD;
#property (nonatomic, strong) NSString * RISK;
// Methods
- (id) initWithID: (NSString *) hazardsID andROUTE: (NSString *) hazardsROUTE andADDRESS: (NSString *) hazardsADDRESS andLATITUDE: (NSString *) hazardsLATITUDE andLONGITUDE: (NSString *) hazardsLONGITUDE andHAZARD: (NSString *) hazardsHAZARD andRISK: (NSString *) hazardsRISK;
#end
Hazards.m
#import "Hazards.h"
#implementation Hazards
#synthesize coordinate, title, subtitle, ID, ROUTE, ADDRESS, LATITUDE, LONGITUDE, HAZARD, RISK, latitude, longitude;
- (id) initWithID: (NSString *) hazardsID andROUTE: (NSString *) hazardsROUTE andADDRESS: (NSString *) hazardsADDRESS andLATITUDE: (NSString *) hazardsLATITUDE andLONGITUDE: (NSString *) hazardsLONGITUDE andHAZARD: (NSString *) hazardsHAZARD andRISK: (NSString *) hazardsRISK {
self = [super init];
if (self)
{
ID = hazardsID;
ROUTE = hazardsROUTE;
ADDRESS = hazardsADDRESS;
LATITUDE = hazardsLATITUDE;
LONGITUDE = hazardsLONGITUDE;
HAZARD = hazardsHAZARD;
RISK = hazardsRISK;
latitude = [hazardsLATITUDE doubleValue]; // convert the string hazardsLatitude to a double here
longitude = [hazardsLONGITUDE doubleValue]; // convert the string hazardsLongitude to a double here
}
return self;
}
-(NSString *)title
{
return self.HAZARD;
}
-(NSString *)subtitle
{
return self.ADDRESS;
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "Hazards.h"
#interface ViewController : UIViewController
#property (nonatomic, strong) NSMutableArray *json;
#property (nonatomic, strong) NSMutableArray *hazardsArray;
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#pragma mark - Methods
-(void) retrieveData;
#end
ViewController.m
#import "ViewController.h"
#import "Hazards.h"
#interface ViewController ()
#end
// Railway Street Ballymena Coordinates
#define BALLYMENA_LATITUDE 54.857719;
#define BALLYMENA_LONGITUDE -6.280654;
// Span
#define THE_SPAN 0.01f;
#define getDataURL #"www.ryanball.net/royalmail/json.php"
#implementation ViewController
#synthesize json, hazardsArray, mapView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Create the region
MKCoordinateRegion myRegion;
// Center
CLLocationCoordinate2D center;
center.latitude = BALLYMENA_LATITUDE;
center.longitude = BALLYMENA_LONGITUDE;
//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span = span;
// Set our mapview
[mapView setRegion:myRegion animated: YES];
// Annotation
NSMutableArray *locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Hazards *myAnn;
// Pin to show Royal Mail Ballymena delivery office
myAnn = [[Hazards alloc] init];
location.latitude = BALLYMENA_LATITUDE;
location.longitude = BALLYMENA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Royal Mail Ballymena";
myAnn.subtitle = #"111, Railway Street";
[locations addObject:myAnn];
[self.mapView addAnnotations:locations];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Methods
-(void) retrieveData {
NSURL *url = [NSURL URLWithString:getDataURL];
NSData *data = [NSData dataWithContentsOfURL:url];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// Setup our hazards array
hazardsArray = [[NSMutableArray alloc] init];
for (int i =0; i < json.count; i++) {
// Create hazard object
NSString *hazardsID = [[json objectAtIndex:i] objectForKey:#"ID"];
NSString *hazardsROUTE = [[json objectAtIndex:i] objectForKey:#"ROUTE"];
NSString *hazardsADDRESS = [[json objectAtIndex:i] objectForKey:#"ADDRESS"];
NSString *hazardsLATITUDE = [[json objectAtIndex:i] objectForKey:#"LATITUDE"];
NSString *hazardsLONGITUDE = [[json objectAtIndex:i] objectForKey:#"LONGITUDE"];
NSString *hazardsHAZARD = [[json objectAtIndex:i] objectForKey:#"HAZARD"];
NSString *hazardsRISK = [[json objectAtIndex:i] objectForKey:#"RISK"];
Hazards *myHazards = [[Hazards alloc] initWithID:hazardsID andROUTE:hazardsROUTE andADDRESS:hazardsADDRESS andLATITUDE:hazardsLATITUDE andLONGITUDE:hazardsLONGITUDE andHAZARD:hazardsHAZARD andRISK:hazardsRISK];
// Add our hazards object to our hazards array
[hazardsArray addObject:myHazards];
}
[self.mapView addAnnotations:hazardsArray];
}
#end
Here is the error log I get in the console:
2013-04-25 09:04:43.628 RoyalMailApp[6596:c07] -[Hazards setCoordinate:]: unrecognized selector sent to instance 0x8c63a60
2013-04-25 09:04:43.629 RoyalMailApp[6596:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Hazards setCoordinate:]: unrecognized selector sent to instance 0x8c63a60'
*** First throw call stack:
(0x1b3c012 0x1458e7e 0x1bc74bd 0x146c7ea 0x1b2bcf9 0x1b2b94e 0x2698 0x47e1c7 0x47e232 0x3cd3d5 0x3cd76f 0x3cd905 0x3d6917 0x39a96c 0x39b94b 0x3accb5 0x3adbeb 0x39f698 0x1a97df9 0x1a97ad0 0x1ab1bf5 0x1ab1962 0x1ae2bb6 0x1ae1f44 0x1ae1e1b 0x39b17a 0x39cffc 0x215d 0x2085 0x1)
libc++abi.dylib: terminate called throwing an exception
(lldb)
Related
I have created Author class like this :
#interface Author : NSObject{
NSString *authorID;
NSString *email;
NSString *userName;
NSString *password;
NSString *jenisKelamin;
NSString *alamat;
NSString *kota;
NSString *telepon;
NSString *pekerjaan;
NSString *nama;
NSString *tanggalDaftar;
NSString *status;
NSString *lastLogin;
NSString *publishPhoto;
NSString *komentar;
NSString *balasKomentar;
NSString *newsLetter;
}
#property (nonatomic, retain)NSString *authorID;
#property (nonatomic, retain)NSString *email;
#property (nonatomic, retain)NSString *userName;
#property (nonatomic, retain)NSString *password;
#property (nonatomic, retain)NSString *jenisKelamin;
#property (nonatomic, retain)NSString *alamat;
#property (nonatomic, retain)NSString *kota;
#property (nonatomic, retain)NSString *telepon;
#property (nonatomic, retain)NSString *pekerjaan;
#property (nonatomic, retain)NSString *nama;
#property (nonatomic, retain)NSString *tanggalDaftar;
#property (nonatomic, retain)NSString *status;
#property (nonatomic, retain)NSString *lastLogin;
#property (nonatomic, retain)NSString *publishPhoto;
#property (nonatomic, retain)NSString *komentar;
#property (nonatomic, retain)NSString *balasKomentar;
#property (nonatomic, retain)NSString *newsLetter;
#end
and read json like this :
imageArray = [[NSMutableArray alloc]init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc]initWithContentsOfURL:url];
NSError *jsonParsingError = nil;
id myJson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonParsingError];
NSDictionary *imageList;
for (int i=0; i<[myJson count]; i++) {
imageList=[myJson objectAtIndex:i];
currentImage = [ImageList alloc];
currentImage.imageID=[imageList valueForKey:#"id"];
currentImage.tanggal=[imageList valueForKey:#"tanggal"];
currentImage.judul=[imageList valueForKey:#"judul"];
currentImage.namaFile=[imageList valueForKey:#"nama_file"];
currentImage.deskripsi=[imageList valueForKey:#"deskripsi"];
currentImage.user=[imageList valueForKey:#"user"];
currentImage.status=[imageList valueForKey:#"status"];
currentImage.views=[imageList valueForKey:#"views"];
currentImage.rating=[imageList valueForKey:#"rating"];
currentImage.totalRating=[imageList valueForKey:#"total_rating"];
currentImage.totalPerating=[imageList valueForKey:#"total_perating"];
currentImage.imageThemeID=[imageList valueForKey:#"tema"];
currentImage.bayesianRating=[imageList valueForKey:#"bayesian_rating"];
currentImage.imageURL=[imageList valueForKey:#"img_url"];
NSDictionary *authorDict = [imageList objectForKey:#"author"];
currentImage.author = [[[Author alloc] init] autorelease];
currentImage.author.authorID = [authorDict valueForKey:#"id"];
currentImage.author.email = [authorDict valueForKey:#"email"];
currentImage.author.userName = [authorDict valueForKey:#"username"];
currentImage.author.password = [authorDict valueForKey:#"password"];
currentImage.author.jenisKelamin = [authorDict valueForKey:#"jenis_kelamin"];
currentImage.author.alamat = [authorDict valueForKey:#"alamat"];
currentImage.author.kota = [authorDict valueForKey:#"kota"];
currentImage.author.telepon = [authorDict valueForKey:#"telepon"];
currentImage.author.pekerjaan = [authorDict valueForKey:#"pekerjaan"];
currentImage.author.nama = [authorDict valueForKey:#"nama"];
currentImage.author.tanggalDaftar = [authorDict valueForKey:#"tanggal_daftar"];
currentImage.author.status = [authorDict valueForKey:#"status"];
currentImage.author.lastLogin = [authorDict valueForKey:#"last_login"];
[imageArray addObject:currentImage];
[currentImage release];
return self;
}
But if I try to get the value using :
jsonImage =[[JSONReader alloc]loadImageList:newURL];
ImageList *currentImage;
currentImage = [[jsonImage imageArray]objectAtIndex:0];
[jsonTheme release];
if([jsonImage.imageArray count]>0){
NSLog(#"getting image starting");
NSURL *imageURL=[NSURL URLWithString:currentImage.imageURL];
NSLog(#"image URL from array : %#", currentImage.imageURL);
NSData *imageData=[NSData dataWithContentsOfURL:imageURL];
imgTemp = [UIImage imageWithData:imageData];
self.imgImage.image = imgTemp;
NSLog(#"getting image stop");
lblDate.text = currentImage.tanggal;
lblDescription.text = currentImage.deskripsi;
lblSummary.text = currentImage.judul;
Author *currentAuthor = currentImage.author;
lblUser.text = currentAuthor.userName;
[currentImage release];
}
lblUser.text = currentTheme.author.userName; the result of lblUser is null.
when I tried to debug, the value of userName have index :
currentAuthor Author * 0x071a9a20
NSObject NSObject
authorID NSString * 0x0753e700
[0] id 0x071a4ad0
[0] id
email NSString * 0x075403a0
[0] id 0x071a58e0
userName NSString * 0x0753fef0
[0] id 0x071a5930
can you tell me how to get currentAuthor values ?
I think , while releasing currentImage . value of author also changed.
Please do the following changes and try it
Author *currentAuthor =[ currentImage.author copy];
When I use this code to try and call Lat & Long coordinates from a MySQL database (and display them on a MapView), the app runs fine. Everything appears to work, but for some reason, xcode pauses the simulator before the map loads, and throws me a SIGABRT. Any idea why? See below:
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController <MKMapViewDelegate>
#property (nonatomic, strong) IBOutlet MKMapView *mapView;
#property (nonatomic, retain) NSMutableArray *dispensaries;
#property (nonatomic, retain) NSMutableData *data;
#end
MapViewController.m
#import "MapViewController.h"
#import "MapViewAnnotation.h"
#implementation MapViewController
#synthesize mapView;
#synthesize dispensaries;
#synthesize data;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidUnload];
NSLog(#"Getting Device Locations");
NSString *hostStr = #"http://stylerepublicmagazine.com/dispensaries.php";
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:hostStr]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
NSLog(#"server output: %#", serverOutput);
NSMutableArray *array = (NSMutableArray *)dispensaries;
dispensaries = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
for (NSDictionary *dictionary in array) {
CLLocationCoordinate2D coord = {[[dictionary objectForKey:#"lat"] doubleValue], [[dictionary objectForKey:#"lng"] doubleValue]};
MapViewAnnotation *ann = [[MapViewAnnotation alloc] init];
ann.title = [dictionary objectForKey:#"Name"];
ann.coordinate = coord;
[mapView addAnnotation:ann];
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
self.mapView.delegate = self;
}
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"You Are Here";
point.subtitle = #"Your current location";
[self.mapView addAnnotation:point];
}
Ok, so now you have the JSON. You are going to have to decode that using NSXMLParser. Or, if you want to turn that into objects, you could use my open source library on GitHub, which allows you to simply implement NSCoding protocol and instantiate objects (or encode them) as JSON. That's here.
I have a UIViewController inside of which I put a UIWebView
Then I added this to the .h file:
#import <UIKit/UIKit.h>
#interface BuildBusinessController : UIViewController
#property (weak, nonatomic) IBOutlet UIWebView *theWebView;
#end
and have this as the .m file
#import "BuildBusinessController.h"
#interface BuildBusinessController ()
#end
#implementation BuildBusinessController
#synthesize theWebView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
theWebView.delegate = self;
}
- (void)viewDidUnload
{
[self setTheWebView:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)viewDidAppear:(BOOL)animated
{
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"build_business" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:htmlFile];
NSURLRequest *rq = [NSURLRequest requestWithURL:url];
[theWebView loadRequest:rq];
}
#end
But the build_business.html file is not rendering inside the view, and also I get a warning on this line: theWebView.delegate = self; which says:
Assigning to id 'UIWebViewDelegate from incompatible type BuildBusinessController *const_string
Would anyone know what I am doing wrong here? It feels I am forgetting some one small thing :)
In addition to F.X. answer, I think you forgot to add this in viewDidAppear (after loadRequest):
[self.view addSubview:theWebView];
Update: The issue is caused by OP failing to configure delegate for UIWebView in Storyboard. The code snippet provided here will only work if you are coding it manually. Otherwise, as stated by #F.X. in the comments below, Storyboard will implement this automatically.
You're just forgetting UIWebViewDelegate on your class definition :
#import <UIKit/UIKit.h>
#interface BuildBusinessController : UIViewController <UIWebViewDelegate>
#property (weak, nonatomic) IBOutlet UIWebView *theWebView;
#end
I am trying to use an NSMutableDictionary in a view controller to load an image and text into a detail view controller when an image is tapped. I am new to programming and I am trying to understand. Could someone please help.
Here is my code in the view controller 1 .m
- (void) coverflowView:(TKCoverflowView*)coverflowView coverAtIndexWasDoubleTapped:(int)index{
SomeDetailViewController *detailViewController = [[SomeDetailViewController alloc] initWithNibName:#"SomeDetailViewController" bundle:nil];
if ((int)index == 0) {
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"0002.jpg", #"imagekey",
#"This is #1", #"textkey", nil];
NSLog(#"%#", [myDictionary objectForKey:#"imagekey"]);
NSLog(#"%#", [myDictionary objectForKey:#"textkey"]);
}
[self.navigationController pushViewController:detailViewController animated:YES];
}
when I build and run this the image key and text key are called but don't show up in the detail view controller.
my detailViewController.h
#import <QuartzCore/QuartzCore.h>
#interface SomeDetailViewController : UIViewController < UITextViewDelegate, UINavigationControllerDelegate>{
IBOutlet UIImageView *imageView;
IBOutlet UITextView *myText;
NSString *imagekey;
NSMutableDictionary *myDictionary;
NSString *textkey;
}
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#property (nonatomic, retain) IBOutlet UITextView *myText;
#property (nonatomic, retain) NSString *imagekey;
#property (nonatomic, retain) NSString *textkey;
#property (nonatomic, retain) NSMutableDictionary *myDictionary;
#end
and my detailViewContoller .m
#synthesize myDictionary;
- (void)viewDidLoad
{
[super viewDidLoad];
imageView .image = [[UIImage alloc] init];
self.imageView.image =[UIImage imageNamed:[(NSMutableDictionary *)myDictionary objectForKey:#"imagekey"]];
self.myText.text =[(NSMutableDictionary *)myDictionary objectForKey:#"textkey"];
}
I know this is similar to another post but I was advise not to use NSUsersDefaults so I am trying this.
There are no errors but nothing shows up
I am able to pull JSON results and map them to the db. However, as soon as I try and map the entity to my subclass, it seems that my mapping breaks.
JSON Sample:
{"Customers":[{"Customer":{"Active":"Y","BranchID":0,"CustomerID":"SMCJIMB00736253","CustomerIdentifier":"","CustomerTypeID":0,"Name":""}}]}
Setup:
// Initialize RestKit
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:TEST_SERVICES_ROOT];
// Initialize object store
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:RKDefaultSeedDatabaseFileName];
Mapping:
RKManagedObjectMapping* customerMapping = [RKManagedObjectMapping mappingForClass:[Customer class]];
customerMapping.primaryKeyAttribute = #"customerID";
[customerMapping mapKeyPathsToAttributes:#"Active", #"active", nil];
[customerMapping mapKeyPathsToAttributes:#"BranchID", #"branchID", nil];
[customerMapping mapKeyPathsToAttributes:#"CustomerID", #"customerID", nil];
[customerMapping mapKeyPathsToAttributes:#"CustomerIdentifier", #"customerIdentifier", nil];
[customerMapping mapKeyPathsToAttributes:#"CustomerTypeID", #"customerTypeID", nil];
[customerMapping mapKeyPathsToAttributes:#"Name", #"name", nil];
Add Mapping:
[objectManager.mappingProvider setMapping:customerMapping forKeyPath:#"Customers.Customer"];
Call WS:
// Load the object model via RestKit
RKObjectManager* objectManager = [RKObjectManager sharedManager];
NSString *url = [NSString stringWithFormat:SERVICE_CUSTOMERS,#"0",#"1",#"100"];
[objectManager loadObjectsAtResourcePath:url delegate:self block:^(RKObjectLoader* loader) {
loader.objectMapping = [objectManager.mappingProvider objectMappingForClass:[Customer class]];
}];
#interface Customer : NSManagedObject
#property (nonatomic, retain) NSString* active;
#property (nonatomic, retain) NSNumber* branchID;
#property (nonatomic, retain) NSString* customerID;
#property (nonatomic, retain) NSString* customerIdentifier;
#property (nonatomic, retain) NSNumber* customerTypeID;
#property (nonatomic, retain) NSString* name;
//populated via fetch predicate
#property (nonatomic, retain) NSArray* customerAddress;
#end
#implementation Customer
#dynamic active;
#dynamic branchID;
#dynamic customerID;
#dynamic customerIdentifier;
#dynamic customerTypeID;
#dynamic name;
//populated via fetch predicate
#dynamic customerAddress;
#end
This works fine as long as I don't try and map the Customer class to the Entity in the data model. Ultimately, I am trying to use my Customer class as a MKAnnotation, but I can't since I cant provide a concrete implementation class. I'm sure that there is some sort of misunderstanding of RestKit to blame. I see that the RKTwitterCoreData has the RKStatus as a concrete subclass.
#end
Ok,
I figured it out after much trial and error! The issue was that I needed to set my rootKeyPath on my mapping to match the rootkeyPath that I use when I added the mapping to the mapping provider. The RKTwitterCoreData client does not do this, but I needed to for whatever reason.
RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class]];
userMapping.rootKeyPath = #"User";
userMapping.primaryKeyAttribute = #"userName";
[userMapping mapKeyPathsToAttributes:#"Authenticated", #"authenticated", nil];
................
[objectManager.mappingProvider setMapping:userMapping forKeyPath:#"User"];