I am at a beginner level of iOS programming. I am using Xcode 4.2 with iOS Simulator 5.0.
I am making the quick start tutorial app using iOS documentation Address Book programming Guide and I'm following all the steps of the tutorial but I get a strange error in this code:
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
NSString *name;
name = (NSString *) ABRecordCopyValue(person, kABPersonFirstNameProperty);
self.firstName.text=name;
name=( NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
self.lastName.text=name;
[self dismissModalViewControllerAnimated:YES];
return NO;
}
at line:
name = (NSString *) ABRecordCopyValue(person, kABPersonFirstNameProperty);
I get the error Cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'NSString *' requires a bridged cast
What am I doing wrong here ?
Please check out this link which has been updated with the latest:
NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person,
kABPersonFirstNameProperty);
or
NSString* name = (__bridge NSString*)ABRecordCopyValue(person,
kABPersonFirstNameProperty);
Related
I want to parse a .csv file. For this I use the CHCSV Parser. But when I push into the view where the parser should start parsing, the app crashes.
Terminating app due to uncaught exception 'NSMallocException', reason:
'* -[NSConcreteMutableData appendBytes:length:]: unable to allocate
memory for length (4294967295)'
NSString *filePath = #"http://somewhere.com/test.csv";
NSString *fileContent = [NSString stringWithContentsOfURL:[NSURL URLWithString:filePath] encoding:NSUTF8StringEncoding error:nil];
self.csvParser = [[CHCSVParser alloc] initWithContentsOfCSVFile:fileContent];
Edit:
I'm developing for iOS 6+. Thanks for the great comments and answers. I hope to get the right solution.
Input Stream
It doesn't work. When I want to work with the input stream the app crashes because of the wrong encoding.
Incompatible integer to pointer conversion sending 'int' to
parameter of type 'NSStringEncoding *' (aka 'unsigned int *')
NSData *downloadData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://example.com/test.csv"]];
NSInputStream *stream = [NSInputStream inputStreamWithData:downloadData];
self.csvParser = [[CHCSVParser alloc] initWithInputStream:stream usedEncoding:NSUTF8StringEncoding delimiter:#";"];
self.csvParser.delegate = self;
[self.csvParser parse];
CSV-String
NSString *filePath = #"http://example.com/test.csv";
NSString *fileContent = [NSString stringWithContentsOfURL:[NSURL URLWithString:filePath] encoding:NSUTF8StringEncoding error:nil];
self.csvParser = [[CHCSVParser alloc] initWithCSVString:fileContent];
self.csvParser.delegate = self;
[self.csvParser parse];
This parse only (null).
Final Edit: Dave, the author of CHCSVParser, updated his code on github, so this problem should be solved when you use the most recent version. Get it now!
Okay, here we go:
First add the following code in CHCSVParser.m:
In method - (void)_sniffEncoding at the very beginning you have:
uint8_t bytes[CHUNK_SIZE];
NSUInteger readLength = [_stream read:bytes maxLength:CHUNK_SIZE];
[_stringBuffer appendBytes:bytes length:readLength];
[self setTotalBytesRead:[self totalBytesRead] + readLength];
change it to:
uint8_t bytes[CHUNK_SIZE];
NSUInteger readLength = [_stream read:bytes maxLength:CHUNK_SIZE];
if (readLength > CHUNK_SIZE) {
readLength = CHUNK_SIZE;
}
[_stringBuffer appendBytes:bytes length:readLength];
[self setTotalBytesRead:[self totalBytesRead] + readLength];
After that changed I got only null values so I changed the file path (in the sample project it is located in the main(), however I did the parsing in viewDidLoad.
Make sure you copied the file in your bundle directory for that to work!
file = [NSBundle pathForResource:#"Test" ofType:#"scsv" inDirectory:[[NSBundle mainBundle] bundlePath]];
Edit:
When you say you need to download the file you can do following (but notice that this is quick and dirty solution especially on mobile devices)
NSData *downloadData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.yourdomain.tld/Test.scsv"]];
NSInputStream *stream = [NSInputStream inputStreamWithData:downloadData];
The last line is the important one here you need to change.
Hope that solves your issue.
Edit 2:
I've just created a repository with a demo project for you where the code actually works. Perhaps you can find out what you do wrong (or at least different). Here is the link.
Edit 3:
Change
self.csvParser = [[CHCSVParser alloc] initWithInputStream:stream usedEncoding:NSUTF8StringEncoding delimiter:#";"];
to
self.csvParser = [[CHCSVParser alloc] initWithInputStream:stream usedEncoding:&encoding delimiter:';'];
I know [[UIDevice currentDevice] uniqueIdentifier] is being rejected, I used :
- (NSString *) uniqueDeviceIdentifier{
NSString *macaddress = [[UIDevice currentDevice] macaddress];
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
NSString *stringToHash = [NSString stringWithFormat:#"%#%#",macaddress,bundleIdentifier];
NSString *uniqueIdentifier = [stringToHash stringFromMD5];
return uniqueIdentifier;
}
If my method is not approved by Apple, what method can I get a unique identifier?
This project does something similar to what you're doing: https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5. I believe it is being accepted by Apple for now. To actually answer your question, there is no other (public) way of getting a id that is not only unique but the same for every app. #Vishal's method of using:
+ (NSString *)GetUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
and #JeffWolski's method of using:
[[NSUUID UUID] UUIDString];
work if you don't need the device id to be consistant between apps and just need a way to identify that specific device within your own. If you need a device ID that works between apps, you will need to use the devices MAC address either using your code or a open source project.
UPDATE
I just found another solution. You can use [[UIDevice currentDevice] identifierForVendor]. Again, this device id will be unique to your app. http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html#//apple_ref/occ/instp/UIDevice/identifierForVendor
This is new in iOS 6. It gives you a UUID that conforms to RFC 4122.
[[NSUUID UUID] UUIDString];
Use this CFUUIDCreate() to create a UUID:
+ (NSString *)GetUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
And the UDID is only deprecated in iOS 5.
One thing you could do it use openUDID to replace it.
Hey guys, I'm receiving a SIGABRT when trying to use an instance variable for anything but an NSLOG :
//Class_X.H
#interface MeldingController : UIViewController
{
NSString *refURLAsString;
}
#property (nonatomic, retain) NSString *refURLAsString;
//Class_X.M
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
self.refURLAsString = [info objectForKey:UIImagePickerControllerReferenceURL];
NSLog(#"%#",self.refURLAsString);//Successfully outputs the ReferenceURL string
}
-(void)function_abc
{
NSLog(#"%#",self.refURLAsString);//Successfully outputs the ReferenceURL string
NSURL *URL = [NSURL URLWithString:self.refURLAsString]; //SIGABRT
//Or even trying to make another string using refUrlAsString
NSString *string = [[NSString alloc]init];
string = self.refURLAsString;//SIGABRT
}
iPhone Simulator iOS version 4.3, Xcode 4.
Any ideas anyone? cheers.
Your refURLAsString is of type NSString *, but [info objectForKey:UIImagePickerControllerReferenceURL] should return a NSURL * instance according to the docs. You want:
self.refURLAsString = [[info objectForKey:UIImagePickerControllerReferenceURL] absoluteString];
The reason why the NSLog works is because it calls the description method on each object that is to be printed via the %# sequence, and that does return a string. But refURLAsString is pointing to a NSURL instead of a NSString, and that makes [NSURL URLWithString:self.refURLAsString]; crash.
try this
string =[refURLAsString copy];
Your code is screwing up refURLAsString. I can't tell you how from the posted code. Activate NSZombieEnabled for details.
Not sure exactly whats the issue is, but try string = [NSString stringWithFormat:#"%#",self.refURLAsString]; and see if it crashes here too
NSString *string = [NSString stringWithFormat:#"%#",self.refURLAsString];
no need to alloc here
NSString* urlEncode(NSString * url)
{
string inStr = StringFromNSString(url);
CFStringRef inStringRef = CFStringCreateWithCString( kCFAllocatorDefault, inStr.c_str(), kCFStringEncodingUTF8 );
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)inStringRef,NULL,(CFStringRef)#"!*’();:#&=+$,/?%#[]",kCFStringEncodingUTF8 );
return encodedString;
}
I am using above method to encode url... even though my app is crashing saying
<body>
<div id="content">
<h1>An Error Was Encountered</h1>
<p>The URI you submitted has disallowed characters.</p> </div>
</body>
</html>
terminate called after throwing an instance of 'std::invalid_argument'
what():
Any idea.. What is wrong with my code?
FYI: It is crashing in this method JSONNode jsonObject0 = libJSON::parse( inResponseData );
UPDATED: The server which i am sending message is UNIX server is it causing problem?
You don't need to create the inStr or inStringRef temporary variables. The types NSString* and CFStringRef are "toll free bridge" types. These types are interchangable with just a simple cast.
You can find more information about toll free bridging here: http://www.mikeash.com/pyblog/friday-qa-2010-01-22-toll-free-bridging-internals.html
That said, you can simplify your method to just the following:
-(NSString*) urlEncode
{
NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)self, NULL, (CFStringRef)#"!*'();:#&=+$,/?%#[]", kCFStringEncodingUTF8 );
return [encodedString autorelease];
}
The above is best implemented as an NSString category (note the use of self as the value to encode).
This works fine for me. I use CFSTR instead of (CFStringRef)#"!*’();:#&=+$,/?%#[]"
- (NSString *)encodedURLParameterString {
NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)self,
NULL,
CFSTR(":/=,!$& '()*+;[]##?"),
kCFStringEncodingUTF8);
return [result autorelease];
}
You can try this
NSString *sampleUrl = #"http://www.google.com/search.jsp?params=Java Developer";
NSString* encodedUrl = [sampleUrl stringByAddingPercentEscapesUsingEncoding:
NSASCIIStringEncoding];
You need to make sure that you're not URL encoding more than you need. If you're going to be using this encoding string as part of an actual URL, then you should know that there are only portions of the URL that are supposed to be encoded, namely the query string (there are other bits as well, but 95% of the time, this has to do with the query).
In other words, your URL should be:
scheme://host/path?<key>=<value>&<key>=<value>
In this, ONLY the stuff inside the angle brackets (<key> and <value>) should be URL encoded.
It was the problem in UNIX server... It was giving wrong data.
NSString *encodedstring = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(__bridge CFStringRef)yoururlstring,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8);
this code works perfect
Here is the best way to encode the formatted URLString:
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Instead of using below as it has some memory management issues.
NSString *encodedstring = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(__bridge CFStringRef)yoururlstring,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8);
Really quick question that is driving me INSANE. I was wondering if someone could tell me why this line is leaking?
NSString *post = [NSString stringWithFormat:#"<someXML><tagWithVar=%#></tagWithVar></someXML>",var];
post = [NSString stringWithFormat:#"xmlValue=%#",(NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)post,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8 )];
I am just encoding a string into a URL format. From my understanding, stringWithFormat: should return an autoreleased object. Apparently that is not the case. It works, but leaks. Any ideas??
You are using the method CFURLCreateStringByAddingPercentEscapes. If a Core Foundation function has "Create" in its name, it means that you own the returned object. In other words, you'll need to release the CFStringRef returned by CFURLCreateStringByAddingPercentEscapes.
NSString *post = [NSString stringWithFormat:#"...", var];
CFStringRef stringRef = CFURLCreateStringByAddingPercentEscapes(...);
post = [NSString stringWithFormat:#"xmlValue=%#",(NSString *)stringRef];
CFRelease(stringRef);