I'm building an app that works with MapKit and I need to get coordinates from Google Maps.
I made a function that does this (and through debugging I know I get the good coordinates), but it then crashes when I try to assign it to my event object's coordinates.
Below is the code and I've clearly commented with // <---------------- where it fails...
AppDelegate.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "MapViewController.h"
#import "Event.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate, MKMapViewDelegate, CLLocationManagerDelegate>{
CLLocationManager *locationManager;
}
//-(void)makeTestData:(int)amount;
-(void) addressLocation:(NSString*)adres:(Event*)event;
#property (strong, nonatomic) UIWindow *window;
//#property (strong, nonatomic) NSMutableArray *events;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "ListViewController.h"
#import "Event.h"
#import <RestKit/RestKit.h>
#implementation AppDelegate{
NSMutableArray *events;
/* for test data */
NSMutableArray *titles;
}
#synthesize window = _window;
//#synthesize events;
-(void) addressLocation:(NSString*)adres: (Event*)event {
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv&key=MYKEY",
[adres stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSArray *listItems = [locationString componentsSeparatedByString:#","];
double latitude = 0.0;
double longitude = 0.0;
if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:#"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else {
//Show error
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude; // <----- Checked in debugging, coords are good
event.coordinate.latitude = latitude; // <----- can't assign the latitude here =/
event.coordinate.longitude = longitude; // <----- can't assign the longitude here =/
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// START COMMUNICATOIN WITH REST INTERFACE
//RKClient* client = [RKClient clientWithBaseURL:#"link"];
//NSLog(#"I am your RKClient singleton : %#", [RKClient sharedClient]);
// -------------------TEST OBJECTS
//makeTestData(3);
events = [NSMutableArray arrayWithCapacity:3];
titles = [NSMutableArray arrayWithCapacity:3];
[titles addObject:#"Gent Jazz Festival"];
[titles addObject:#"Over blauw bloed en witte billenbijters - zoektocht in het Prinsenhof (zonder gids)"];
[titles addObject:#"DuveltTent"];
Event *event = [[Event alloc] init];
event.title = [titles objectAtIndex:(rand()*100)%3];
event.description = #"omminommie!!!";
event.zone = #"fzfzefez";
event.gemeente = #"Gent";
event.plaats = #"";
event.straat = #"Sint-Veerleplein";
NSString *adres = [NSString stringWithFormat:#"%#, %#", event.gemeente, event.straat];
[self addressLocation:adres:event]; //<---- This function fails, see above for def
event.zone = #"blub";
[events addObject:event];
...
---- EDIT
Like the code is, as above, it doesn't even compile and gives the error:
Expression is not assignable
When I use = location (which I did before) as suggested above I get the following error:
2012-07-13 17:14:20.608 Zone-It-new[565:707] -[Event setCoordinate:]: unrecognized selector sent to instance 0x283ab0
2012-07-13 17:14:20.621 Zone-It-new[565:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Event setCoordinate:]: unrecognized selector sent to instance 0x283ab0'
*** First throw call stack:
(0x3748488f 0x35189259 0x37487a9b 0x37486a83 0x373e1650 0x6a319 0x6a5c9 0x31190cab 0x3118a7dd 0x31158ac3 0x31158567 0x31157f3b 0x33b9a22b 0x37458523 0x374584c5 0x37457313 0x373da4a5 0x373da36d 0x3118986b 0x31186cd5 0x6a097 0x6a03c)
terminate called throwing an exception
Here are my event.h and event.m
event.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#import <RestKit/RestKit.h>
#interface Event : NSObject <MKAnnotation>
// required property from mkanotation
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
// Optional
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *description;
#property (nonatomic, copy) NSString *zone;
#property (nonatomic, assign) NSString *gemeente;
#property (nonatomic, copy) NSString *straat;
#property (nonatomic, assign) int deelnemers;
#property (nonatomic, copy) NSDate *start;
#property (nonatomic, copy) NSDate *einde;
#property (nonatomic, copy) NSString *plaats;
#property (nonatomic, readonly) int id_nr;
#property (nonatomic, assign) int huisnummer;
#end
event.m
#import "Event.h"
#implementation Event
#synthesize coordinate, title, zone, gemeente, straat, deelnemers, start, einde, plaats, id_nr, huisnummer, description;
#end
Important to note, maybe, is that ARC is on.
Have you tried changing the coordinate property to readwrite? (assign would be a good choice.)
Related
I am new to RestKit and an Objective-C newbie. The JSON that I would like to turn into Objective-C objects has the following format.
{
"id":1,
"ron95":700.0,
"ron92":700.0,
"dieselNormal":700.0,
"dieselSpecial":700.0,
"postDate":1435465383000
}
In Java, the JSON would be represented like this:
public class Price {
private Long id;
private Double ron95;
private Double ron92;
private Double dieselNormal;
private Double dieselSpecial;
private java.util.Date postDate;
...
}
What would the mapping Objective-C class be like and how would you do the mapping using RestKit?
Edit: This is what I think my Objective-C representation should look like. Correct me if I am wrong.
Price.h
#import <Foundation/Foundation.h>
#interface Price : NSObject {
NSInteger id;
double ron95;
double ron92;
double dieselNormal;
double dieselSpecial;
NSDate *postDate;
}
#property (nonatomic) NSInteger id;
#property (nonatomic) double ron95;
#property (nonatomic) double ron92;
#property (nonatomic) double dieselNormal;
#property (nonatomic) double dieselSpecial;
#property (nonatomic, retain) NSDate *postDate;
#end
Price.m
#import "Price.h"
#implementation Price
#synthesize id;
#synthesize ron95;
#synthesize ron92;
#synthesize dieselNormal;
#synthesize dieselSpecial;
#synthesize postDate;
#end
I have been looking into this for a while. I decided to write my own solution. It is very simple and built upon existing Apple functionality. Just go to github and copy the source to your project. Have your Price class inherit from GSObject instead of NSObject.
Write a category for NSDate class with this class method:
+(id) initWithJsonValue:(NSString*)jsonValue
Here is where you would convert the date string
"postDate":1435465383000
to an NSDate probably using a date formatter.
See here: https://github.com/gslinker/GSObject
And here: http://digerati-illuminatus.blogspot.com/2016/01/objective-c-and-json-convert-subclass.html
Here is a sample that I made, notice it has an NSDate object as well.
For your data model object have it inherit from GSObject instead of NSObject. Here is an example of ThingOne with inherits from GSObject:
ThingOne* object1 = [[ThingOne alloc] init];
object1.name = #"John Jones";
NSData* jsonData1 = [object1 toJsonDataWithOptions:NSJSONWritingPrettyPrinted];
NSString *jsonString1 = [object1 toJsonStringWithOptions:NSJSONWritingPrettyPrinted];
NSDictionary<NSString *,id> *dict1 = [GSObject dictionaryWithValues:object1];
NSString *roundTripJson1 = [object1 toJsonStringWithOptions:NSJSONWritingPrettyPrinted];
//
// ThingOne.h
// JasonStuff
//
// Created by Geoffrey Slinker on 12/28/15.
// Copyright © 2015 Slinkworks LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "GSObject.h"
#import "ThingTwo.h"
#interface ThingOne : GSObject
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) ThingTwo *thingTwo;
#property (nonatomic, retain) NSArray *values;
#property (nonatomic, retain) NSDictionary *dict;
#property int myInt;
#property float myFloat;
#property BOOL myBool;
#property (nonatomic, retain) NSNumber* someMoney;
#end
//
// ThingOne.m
// JasonStuff
//
// Created by Geoffrey Slinker on 12/28/15.
// Copyright © 2015 Slinkworks LLC. All rights reserved.
//
#import "ThingOne.h"
#implementation ThingOne
#synthesize name;
#synthesize thingTwo;
#synthesize values;
#synthesize dict;
#synthesize myInt;
#synthesize myFloat;
#synthesize myBool;
#synthesize someMoney;
- (instancetype)init
{
self = [super init];
thingTwo = [[ThingTwo alloc] init];
thingTwo.stuff = #"Thing Two Stuff";
thingTwo.someOtherStuff = #"Thing Two Other Stuff";
NSDateFormatter *dateFormater = [[NSDateFormatter alloc]init];
[dateFormater setDateFormat:#"yyyy-mm-dd"];
thingTwo.someDate = [dateFormater dateFromString:#"1963-10-07"];
values = [NSArray arrayWithObjects:#"Value1", #"Value2", #"Value3", nil];
dict = [NSDictionary dictionaryWithObjectsAndKeys:#"value1", #"key1", #"value2", #"key2", nil];
myInt = 5431;
myFloat = 123.456f;
myBool = YES;
someMoney = [NSNumber numberWithInt:503];
return self;
}
#end
//
// ThingTwo.h
// JasonStuff
//
// Created by Geoffrey Slinker on 12/28/15.
// Copyright © 2015 Slinkworks LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "GSObject.h"
#interface ThingTwo : GSObject
#property (nonatomic, retain) NSString *stuff;
#property (nonatomic, retain) NSString *someOtherStuff;
#property (nonatomic, retain) NSDate *someDate;
#property (nonatomic, retain) NSString *nullString;
#property (nonatomic, retain) NSDate *nullDate;
#end
//
// ThingTwo.m
// JasonStuff
//
// Created by Geoffrey Slinker on 12/28/15.
// Copyright © 2015 Slinkworks LLC. All rights reserved.
//
#import "ThingTwo.h"
#implementation ThingTwo
#synthesize stuff;
#synthesize someOtherStuff;
#synthesize someDate;
- (instancetype)init
{
self = [super init];
someDate = [NSDate date];
return self;
}
#end
Here is an example of the JSON output:
{
"values" : [
"Value1",
"Value2",
"Value3"
],
"myInt" : 5431,
"myFloat" : 123.456,
"myBool" : true,
"someMoney" : "$503.00",
"thingTwo" : {
"stuff" : "Thing Two Stuff",
"nullDate" : null,
"someDate" : "1963-01-07 07:10:00 +0000",
"nullString" : null,
"someOtherStuff" : "Thing Two Other Stuff"
},
"name" : "John Jones",
"dict" : {
"key1" : "value1",
"key2" : "value2"
}
}
have a look at https://github.com/icanzilb/JSONModel, from cocoapods
all (de)serialization is handled automatically for you, even complex structures of array of custom objects.
Been using it, been loving it...
Can someone show me how to initialize an NSMutableOrderedSet?
I tried the following
NSMutableOrderedSet *answerSet = [NSMutableOrderedSet orderedSet];
but hang there an the log is just (lldb)
will insert object Answer
#import "Answer.h"
#import "Survey.h"
#implementation Answer
#dynamic count;
#dynamic text;
#dynamic survey;
#end
EDIT 1:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface Survey : NSManagedObject
#property (nonatomic, retain) NSDate * dateCreated;
#property (nonatomic, retain) NSString * id;
#property (nonatomic, retain) NSString * note;
#property (nonatomic, retain) NSString * question;
#property (nonatomic, retain) NSMutableOrderedSet *answers;
#end
#interface Survey (CoreDataGeneratedAccessors)
- (void)addAnswersObject:(NSManagedObject *)value;
- (void)removeAnswersObject:(NSManagedObject *)value;
- (void)addAnswers:(NSMutableOrderedSet *)values;
- (void)removeAnswers:(NSMutableOrderedSet *)values;
#end
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class Survey;
#interface Answer : NSManagedObject
#property (nonatomic, retain) NSNumber * count;
#property (nonatomic, retain) NSString * text;
#property (nonatomic, retain) Survey *survey;
#end
NSMutableOrderedSet *answerSet = [[NSMutableOrderedSet alloc] initWithCapacity:4];
Answer *ans1 = [NSEntityDescription insertNewObjectForEntityForName:#"Answer"inManagedObjectContext:managedObjectContext];
ans1.text = trimedAns1;
ans1.count = 0;
ans1.survey = survey;
Answer *ans2 = [NSEntityDescription insertNewObjectForEntityForName:#"Answer"inManagedObjectContext:self.managedObjectContext];
ans2.text = trimedAns2;
ans2.count = 0;
ans2.survey = survey;
[answerSet addObject:ans1];
[answerSet addObject:ans2];
[survey setAnswers:answerSet];
NSError *error = nil;
if (![managedObjectContext save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error userInfo]);
} else {
NSLog(#"Saved question : %#", self.question.text);
}
and now I got exception below when saving to core data:
2013-06-27 22:58:33.955 Simple Survey[718:11903] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-many relationship: property = "answers"; desired type = NSSet; given type = __NSOrderedSetM; value = {(
<Answer: 0x8168070> (entity: Answer; id: 0x81c8880 <x-coredata:///Answer/t0F1038D5-DD97-4066-AB7D-E92386A9010B3> ; data: {
count = nil;
survey = "0x81be560 <x-coredata:///Survey/t0F1038D5-DD97-4066-AB7D-E92386A9010B2>";
text = 6;
}),
<Answer: 0x74ec7f0> (entity: Answer; id: 0x74eed40 <x-coredata:///Answer/t0F1038D5-DD97-4066-AB7D-E92386A9010B4> ; data: {
count = nil;
survey = "0x81be560 <x-coredata:///Survey/t0F1038D5-DD97-4066-AB7D-E92386A9010B2>";
text = 7;
})
)}.'
You can do like this:
NSMutableOrderedSet *answerSet = [[NSMutableOrderedSet alloc] initWithCapacity:100];
And reading this will be helpful to you.
Trying to add some annotations for a MapView, but keep getting an ARC Semantic issue: 'No visible #interface for 'MKPointAnnotation' declares the selector initWithTitle:andCoordinate:
I'm fairly new to this so don't really know what it means, if anyone could explain/correct it i'd be grateful.
Here is my viewDidLoad method:
- (void)viewDidLoad
{
CLLocationCoordinate2D location;
location.latitude = (double) 51.501468;
location.longitude = (double) -0.141596;
MKPointAnnotation *newAnnotation = [[MKPointAnnotation alloc] initWithTitle:#"Buckingham Palace" andCoordinate:location];
[self._mapView addAnnotation:newAnnotation];
}
and my header file:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MapViewAnnotation : NSObject <MKAnnotation> {
NSString *title;
CLLocationCoordinate2D coordinate;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;
#end
The initWithTitle:andCoordinate method you created is a method of MapViewAnnotation rather than MKPointAnnotation.
You probably want:
MapViewAnnotation *newAnnotation = [[MapViewAnnotation alloc] initWithTitle:#"Buckingham Palace" andCoordinate:location];
[self._mapView addAnnotation:newAnnotation];
It's trying to tell you it can't find any method that matches the signature of initWithTitle:andCoordinate:
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:coordinate];
[annotation setTitle:#"Buckingham Palace"];
Following a book tutorial and seem to run into a snag with the "isGameCenterAvailable" error.
Apparently it is undeclared. Everything else seems to work however so I just need to figure this part out.
Helloworldlayer .m init method
#import <GameKit/GameKit.h>
GameKitHelper* gkHelper = [GameKitHelper sharedGameKitHelper]; gkHelper.delegate = self;
[gkHelper authenticateLocalPlayer];
Class gameKitLocalPlayerClass = NSClassFromString(#"GKLocalPlayer"); bool isLocalPlayerAvailable = (gameKitLocalPlayerClass != nil);
// Test if device is running iOS 4.1 or higher
NSString* reqSysVer = #"4.1";
NSString* currSysVer = [[UIDevice currentDevice] systemVersion]; bool isOSVer41 = ([currSysVer compare:reqSysVer
options:NSNumericSearch] != NSOrderedAscending);
isGameCenterAvailable = (isLocalPlayerAvailable && isOSVer41);
-(void) onLocalPlayerAuthenticationChanged {
[delegate onLocalPlayerAuthenticationChanged];
}
-(void) authenticateLocalPlayer {
GKLocalPlayer* localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.authenticated == NO) {
[localPlayer authenticateWithCompletionHandler: ^(NSError* error) {
[self setLastError:error]; }];
}
}
Gamekit.h
#import "cocos2d.h"
#import <GameKit/GameKit.h>
#protocol GameKitHelperProtocol
-(void) onLocalPlayerAuthenticationChanged; -(void) onFriendListReceived: (NSArray*)friends; -(void) onPlayerInfoReceived:(NSArray*)players; #end
#interface GameKitHelper : NSObject {
id<GameKitHelperProtocol> delegate; bool isGameCenterAvailable; NSError* lastError;
}
#property (nonatomic, retain) id<GameKitHelperProtocol> delegate;
#property (nonatomic, readonly) bool isGameCenterAvailable; #property (nonatomic, readonly) NSError* lastError;
+(GameKitHelper*) sharedGameKitHelper;
// Player authentication, info
-(void) authenticateLocalPlayer;
-(void) getLocalPlayerFriends;
-(void) getPlayerInfo:(NSArray*)players;
#end
helloworld layer.h
#import "GameKitHelper.h"
#interface helloworldlayer : CCLayer <GameKitHelperProtocol>
{
}
gamekithelper. h
#import "cocos2d.h"
#import <GameKit/GameKit.h>
#protocol GameKitHelperProtocol
-(void) onLocalPlayerAuthenticationChanged; -(void) onFriendListReceived:(NSArray*)friends; - (void) onPlayerInfoReceived:(NSArray*)players; #end
#interface GameKitHelper : NSObject {
id<GameKitHelperProtocol> delegate; bool isGameCenterAvailable; NSError* lastError;
}
#property (nonatomic, retain) id<GameKitHelperProtocol> delegate;
#property (nonatomic, readonly) bool isGameCenterAvailable; #property (nonatomic, readonly) NSError* lastError;
+(GameKitHelper*) sharedGameKitHelper;
// Player authentication, info
-(void) authenticateLocalPlayer;
-(void) getLocalPlayerFriends;
-(void) getPlayerInfo:(NSArray*)players;
#end
The problem is you never actually declare isGameCenterAvailable. To fix this, do this:
//HelloWorldLayer.h
#property (nonatomic) BOOL isGameCenterAvailable;
//HelloWorldLayer.m
#synthesize isGameCenterAvailable = _isGameCenterAvailable;
UPDATE:
To fix the delegate error, try this:
//HelloWorldLayer.h
#property (nonatomic, retain) id<GameKitHelperProtocol> delegate;
//HelloWorldLayer.m
#synthesize delegate;
Hope this helps!
I have a superclass Question:
import <Foundation/Foundation.h>
#import "Answer.h"
#interface Question : NSObject {
NSString* qId;
NSString* qTitle;
NSString* qNumber;
NSString* sectionId;
NSString* type;
Answer* answer;
}
#property (nonatomic, retain) NSString* qId;
#property (nonatomic, retain) NSString* qTitle;
#property (nonatomic, retain) NSString* qNumber;
#property (nonatomic, retain) NSString* sectionId;
#property (nonatomic, retain) NSString* type;
#property (nonatomic, retain) Answer* answer;
#end
#import "Question.h"
#implementation Question
#synthesize qId, qTitle, qNumber, sectionId, type, answer;
-(id)init
{
if (self = [super init])
{
// Initialization code here
answer = [[Answer alloc]init];
}
return self;
}
-(void) dealloc{
[answer release];
[super dealloc];
}
#end
I have several types of Question, one example is a Slider Question. I want this class to subclass Question:
#import <Foundation/Foundation.h>
#import "Question.h"
#interface SliderQuestion : Question {
(NSString*) min;
(NSString*) max;
}
#property (nonatomic, retain) NSString* min;
#property (nonatomic, retain) NSString* max;
#end
}
#import "SliderQuestion.h"
#implementation SliderQuestion
#synthesize min, max;
#end
Is this the correct way to subclass? Will SliderQuestion inherit the properties contained within Question?
SliderQuestion* s = [[SliderQuestion alloc]init];
NSLog(#"%#", s.qId); //is this valid
Do you really want min and max to be instances of NSString? It seems that floats would be more appropriate.
Also, scrap the () in (NSString *) to remove the warning/error message.
Finally, this is the appropriate way to subclass. An instance of SliderQuestion will inherit all properties and methods of the Question class (and NSObject as well)
Notice the ( and ) around the NSStrings, you might wanna remove those.