How to define a global struct? - ios

I want struct which should be in any controller or in any class ...
Anyone have idea about this ?
Code :
typedef struct Student{
__unsafe_unretained NSString *name;
__unsafe_unretained NSString *lastName;
__unsafe_unretained NSString *firstName;
}student;

To make your struct visible everywhere in the project, import your header file where you defined the structure into your_project_name_Prefix.pch

Related

How to append values in gloabal variables in iOS?

I am very much new to iOS so i don't have an idea.I am developing an application in which i am fetaching data from the server.So i have some of the url from which i will featch the data.I want to decalre all the url in a seperate file & use them in another file.I have created AppConst.h & AppConst.m.
AppConst.h
#import <Foundation/Foundation.h>
#interface AppConstant : NSObject
extern NSString const *BASE_URL;
extern NSString const *LOGIN;
extern NSString const *CREATE_ACCOUNT;
extern NSString const *UPDATE_PROFILE;
extern NSString const *ADD_BUSINESS_CARD;
extern NSString const *ADD_NONBUSINESS_CARD;
extern NSString const *ADD_EVENT_CARD;
#end
AppConst.m
#import "AppConstant.h"
#implementation AppConstant
NSString const *BASE_URL=#"http://localhost:8080/app/v1";
NSString const *LOGIN=#"/login";
NSString const *UPDATE_PROFILE=#"/create_account";
NSString const *ADD_BUSINESS_CARD=#"/addBusinessCard";
NSString const *ADD_NONBUSINESS_CARD=#"addNonBusinessCard";
NSString const *ADD_EVENT_CARD=#"addEventCard";
#end
But i am not able to append the string of BASE_URL with LOGIN url.
I get the error as below
sending 'const_NSString *__strong' to parameter of type "NSString discards qualifiers.
You should declare your constant string as follows:
NSString * const kSomeConstantString = #""; // constant pointer
The former is a constant pointer to an NSString object, while the later is a pointer to a constant NSString object.
Using a NSString * const prevents you from reassigning kSomeConstantString to point to a different NSString object.
The method isEqualToString: expects an argument of type NSString *. If you pass a pointer to a constant string (const NSString *), you are passing something different than it expects.
Besides, NSString objects are already immutable, so making them const NSString is meaningless.
Or else you can declare constant like this also
#define kSomeConstantString #""
better idea to make constants file is to create header file and add all the static constants like below:
// Host Url
#define BASE_URL #"http://localhost:8080/app/v1"
// login Url
#define LOGIN #"/login"
and than add the constants file.h in the parent view controller and than you can use everywhere in the app. and even if you want to append string than you can use the below code the create url from your code:
NSString *loginURL = [NSString stringWithFormat:#"%#%#", BASE_URL, LOGIN];
Thanks, May be help you to learn new things.

detect the class of a property with name in objective-c [duplicate]

This question already has answers here:
property type or class using reflection
(2 answers)
Closed 9 years ago.
I have an NSObject in objective-c at runtime and i want to know the class of a property in this object , i have the name of this property as NSString , how can I do that.
EDIT :
IntrospectionUtility class :
#implementation IntrospectionUtility
// this function returns an array of names of properties
+ (NSMutableArray*) getProperties:(Class)class
{
NSMutableArray *properties = [[NSMutableArray alloc] init];
unsigned int outCount, i;
objc_property_t *objc_properties = class_copyPropertyList(class, &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = objc_properties[i];
const char *propName = property_getName(property);
if(propName) {
NSString *propertyName = [NSString stringWithCString:propName encoding:[NSString defaultCStringEncoding]];
[properties addObject:propertyName];
}
}
free(objc_properties);
return properties;
}
#end
class test :
#interface JustAnExample : NSObject
#property (nonatomic, strong) NSString *a;
#property (nonatomic, strong) NSString *b;
#property (nonatomic, strong) NSString *c;
#property (nonatomic, strong) NSString *d;
#end
#implementation JustAnExample
- (void) justAnExampleTest
{
NSMutableArray *attributes = [IntrospectionUtility getProperties:self.class];
for (NSString *attribute in attributes) {
//i want to know the type of each attributte
}
}
#end
i have the name of this property as NSString
You can use the function class_getProperty(Class cls, const char *name) to find the property for a given class. Then use property_getAttributes(objc_property_t property) to get the property's attributes, including the encoded type string. Read the Declared Properties section of the Objective-C Runtime Programming Guide for more info.

My function can not access self property since code is centralised [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am fairly new at using xCode, so sorry if this question seems strange.
In my app I would like all the views and tableviews to channel their DB (sqlite3) access trough one object. I already got the openDatabase function running but seem to have an issue with the function that creates a new one when none is available.
It all used to work when the code was in the view itself, but centralising it made it a lot more difficult than I had anticipated :(.
below my code for the .h and .m:
beDbAccess.h
//
// beDbAccess.h
// myDiveApp
//
// Created by Jurgen on 07/09/13.
// Copyright (c) 2013 Dictus. All rights reserved.
//
#import "beObject.h"
#import "sqlite3.h"
#interface beDbAccess : NSObject
{
NSArray *path;
NSString *docPath;
NSString *dbPathString;
NSFileManager *fileManager;
}
#property (nonatomic, retain) NSArray *path;
#property (nonatomic) NSString *docPath;
#property (nonatomic) NSString *dbPathString;
#property (nonatomic) NSFileManager *fileManager;
#pragma functions callable from the outside
NSString *openDatabase();
#pragma functions
-(void)createNewDatabase;
#end
=================
beDbAccess.m
//
// beDbAccess.m
// myDiveApp
//
// Created by Lion on 07/09/13.
// Copyright (c) 2013 Dictus. All rights reserved.
//
// LET EROP DAT JE NOOIT '' gebruikt rond de veldnamen in de WHERE CLAUSE !!!
#import "beDbAccess.h"
#implementation beDbAccess
#synthesize path, dbPathString, docPath, fileManager;
NSMutableArray *arrayOfButtons;
sqlite3 *myDb;
NSArray *path;
NSFileManager *fileManager;
NSString *docPath, *dbPathString;
UIRefreshControl *refreshControl;
NSString *openDatabase()
{
sqlite3 *myDb;
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [path objectAtIndex:0];
NSString *dbPathString = [docPath stringByAppendingPathComponent:#"myDb.db"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:dbPathString])
{
const char *dbPath = [dbPathString UTF8String];
if (sqlite3_open(dbPath, &myDb)==SQLITE_OK)
{
NSLog(#" Create Database: EMPTY ...");
/*!*/ [self createNewDatabase]; // This is where the problem lies... Use of undeclared identifier 'self' :(
} else NSLog(#"#Local: db open...");
}
return dbPathString;
}
Functions are not methods conceptually
Functions don't know about a self pointer because they typically don't belong to a class
In your case you have to make the function part of the class OR give it access to the class some other way (which wouldn't be OO style)
e.g.
#interface beDbAccess : NSObject
{
NSArray *path;
NSString *docPath;
NSString *dbPathString;
NSFileManager *fileManager;
}
#property (nonatomic, retain) NSArray *path;
#property (nonatomic) NSString *docPath;
#property (nonatomic) NSString *dbPathString;
#property (nonatomic) NSFileManager *fileManager;
#pragma functions callable from the outside
+ (id)sharedInstance;
-(NSString*)openDatabase;
#pragma functions
-(void)createNewDatabase;
#end
THEN use it from the outside like:
[[beDbAccess sharedInstance] openDatabase];

Using Foundation_EXPORT correctly

I have a file called Event.h:
#interface Event : NSObject
FOUNDATION_EXPORT NSString * const KP_STATUS_NEW
FOUNDATION_EXPORT NSString * const KP_STATUS_APPROVED
FOUNDATION_EXPORT NSString * const KP_STATUS_DELETED
#property (nonatomic, strong) NSString * name;
#property (nonatomic, strong) NSString * description;
#property (nonatomic, strong) NSString * status
I would like programmers who use my SDK to have access to the STATUS strings especially when setting a status for an Event object. Should I be using FOUNDATION_EXPORT like the above?
So that a programmer can just do
Event * myEvent = [[Event alloc] init];
myEvent.status = STATUS_NEW;
?
Is that the way to do it in objective-c?
By the way KP is the common prefix for the project. Should I be prefixing the status with KP or something else? What's the standard?
You can just use extern, rather than FOUNDATION_EXPORT (which I believe is what it is defined as anyway).
Using a common prefix is a good idea, given the lack of namespaces in Objective-C and this goes double for a class called Event which is a very common name.
So something like this, looks OK to me:
#import "KPEvent.h"
KPEvent * myEvent = [[KPEvent alloc] init];
myEvent.status = KP_STATUS_NEW;
or better still:
myEvent.status = KP_EVENT_STATUS_NEW;
if statuses only relate to the event class.
What you don't explain, is why you cannot use an enum, which is more elegant:
typedef enum {
KP_EVENT_STATUS_NEW,
KP_EVENT_STATUS_APPROVED,
KP_EVENT_STATUS_DELETED
} KpEventStatus;
and you can forget about that extern nonsense.

Programmatically/Manually create a MKPlacemark/CLPlacemark

Problem
I have a set of placemark information (country, city, etc) and a Lat/Lon pair. I would like to use this to create an MKPlacemark object.
Discussion
It appears that this class can only be created by
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary *)addressDictionary
whose docs state states
You can create placemark objects manually for entities for which you already have address information, such as contacts in the Address Book. Creating a placemark object explicitly avoids the need to query the reverse geocoder object for the same information.
Perfect! I have already reverse-geocoded and wish to avoid such a query. What can I add to the dictionary?
For a list of strings that you can use for the keys of this dictionary, see the “Address Property” constants in ABPerson Reference. All of the keys in should be at the top level of the dictionary.
Which shows relevant keys
const ABPropertyID kABPersonAddressProperty;
const CFStringRef kABPersonAddressStreetKey;
const CFStringRef kABPersonAddressCityKey;
const CFStringRef kABPersonAddressStateKey;
const CFStringRef kABPersonAddressZIPKey;
const CFStringRef kABPersonAddressCountryKey;
const CFStringRef kABPersonAddressCountryCodeKey;
This falls quite short of the base traits for an MKPlacemark:
Accessing the Location Data
location property
Accessing the Placemark Attributes
name property
addressDictionary property
ISOcountryCode property
country property
postalCode property
administrativeArea property
subAdministrativeArea property
locality property
subLocality property
thoroughfare property
subThoroughfare property
region property
Accessing Geographic Information
inlandWater property
ocean property
Accessing Landmark Information
areasOfInterest property
Fortunately, the actual header file for MKPlacemark's superclass says something about the address dictionary:
// address dictionary properties
#property (nonatomic, readonly) NSString *name; // eg. Apple Inc.
#property (nonatomic, readonly) NSString *thoroughfare; // street address, eg. 1 Infinite Loop
#property (nonatomic, readonly) NSString *subThoroughfare; // eg. 1
#property (nonatomic, readonly) NSString *locality; // city, eg. Cupertino
#property (nonatomic, readonly) NSString *subLocality; // neighborhood, common name, eg. Mission District
#property (nonatomic, readonly) NSString *administrativeArea; // state, eg. CA
#property (nonatomic, readonly) NSString *subAdministrativeArea; // county, eg. Santa Clara
#property (nonatomic, readonly) NSString *postalCode; // zip code, eg. 95014
#property (nonatomic, readonly) NSString *ISOcountryCode; // eg. US
#property (nonatomic, readonly) NSString *country; // eg. United States
#property (nonatomic, readonly) NSString *inlandWater; // eg. Lake Tahoe
#property (nonatomic, readonly) NSString *ocean; // eg. Pacific Ocean
#property (nonatomic, readonly) NSArray *areasOfInterest; // eg. Golden Gate Park
So, I create a dictionary and then pass it like so:
return [[[MKPlacemark alloc] initWithCoordinate:aLocation.coordinate addressDictionary:addressDictionary] autorelease];
Unfortunately, after all that, introspection shows that the information did not stick:
NSLog(#"placemark %# from %#", placemark, addressDictionary);
NSLog(#"has %#", placemark.thoroughfare);
Prints
2012-01-31 20:14:22.545 [15450:1403] placemark <+___,-___> +/- 0.00m from {
administrativeArea = __;
postalCode = _____;
subAdministrativeArea = ___;
subThoroughfare = __;
thoroughfare = "_____";
}
2012-01-31 20:14:22.545[15450:1403] has (null)
Conclusion
So, I'm about at the end here. Has anyone figured out how to create your own MKPlacemark? Thanks.
You can subclass MKPlacemark:
In MyPlacemark.h
#interface MyPlacemark : MKPlacemark
extern NSString * const kCustomPlacemarkAddressThoroughfareKey;
extern NSString * const kCustomPlacemarkAddressSubThoroughfareKey;
extern NSString * const kCustomPlacemarkAddressLocalityKey;
extern NSString * const kCustomPlacemarkAddressSubLocalityKey;
extern NSString * const kCustomPlacemarkAddressAdministrativeAreaKey;
extern NSString * const kCustomPlacemarkAddressSubAdministrativeAreaKey;
extern NSString * const kCustomPlacemarkAddressPostalCodeKey;
extern NSString * const kCustomPlacemarkAddressCountryKey;
extern NSString * const kCustomPlacemarkAddressCountryCodeKey;
#end
In MyPlacemark.m:
#import "MyPlacemark.h"
#implementation MyPlacemark
NSString * const kCustomPlacemarkAddressThoroughfareKey = #"thoroughfare";
NSString * const kCustomPlacemarkAddressSubThoroughfareKey = #"subThoroughfare";
NSString * const kCustomPlacemarkAddressLocalityKey = #"locality";
NSString * const kCustomPlacemarkAddressSubLocalityKey = #"subLocality";
NSString * const kCustomPlacemarkAddressAdministrativeAreaKey = #"administrativeArea";
NSString * const kCustomPlacemarkAddressSubAdministrativeAreaKey = #"subAdministrativeArea";
NSString * const kCustomPlacemarkAddressPostalCodeKey = #"postalCode";
NSString * const kCustomPlacemarkAddressCountryKey = #"country";
NSString * const kCustomPlacemarkAddressCountryCodeKey = #"countryCode";
- (NSString *)thoroughfare
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressThoroughfareKey];
}
- (NSString *)subThoroughfare
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressSubThoroughfareKey];
}
- (NSString *)locality
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressLocalityKey];
}
- (NSString *)subLocality
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressSubLocalityKey];
}
- (NSString *)administrativeArea
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressAdministrativeAreaKey];
}
- (NSString *)subAdministrativeArea
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressSubAdministrativeAreaKey];
}
- (NSString *)postalCode
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressPostalCodeKey];
}
- (NSString *)country
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressCountryKey];
}
- (NSString *)countryCode
{
return [self.addressDictionary objectForKey:kCustomPlacemarkAddressCountryCodeKey];
}
#end
It looks ugly, but it's the only way so far that I've found to work.

Resources