NSScanner unrecognized selector on scanUpToString - objective-c

I use the URL parser class from Dimitris but i encounter a problem when init object trought initWithURLString:
- (id) initWithURLString:(NSString *)url{
self = [super init];
if (self != nil) {
NSString *string = url;
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *tempString;
NSMutableArray *vars = [NSMutableArray new];
//ignore the beginning of the string and skip to the vars
[scanner scanUpToString:#"?" intoString:nil];
while ([scanner scanUpToString:#"&" intoString:&tempString]) {
[vars addObject:[tempString copy]];
}
self.variables = vars;
}
return self;
}
On line [scanner scanUpToString:#"?" intoString:nil]; i get an error:
[NSURL length]: unrecognized selector sent to instance 0x1f8c2050
How is it possible?
EDIT: maybe you want to know how i call URLParser:
URLParser *urlParser = [[URLParser alloc]initWithURLString:[info valueForKey:UIImagePickerControllerReferenceURL]];
UIImagePickerControllerReferenceURL value is : assets-library://asset/asset.PNG?id=8D2F0449-11A3-4962-9D60-C446831645D7&ext=PNG

You pass a NSURL to initWithURLString, but you should use it with NSString like this:
NSString* urlString = [NSString stringWithFormat:#"%#",[info valueForKey:UIImagePickerControllerReferenceURL]];
URLParser *parser = [[[URLParser alloc] initWithURLString:urlString] autorelease];

Related

FatSecret API "invalid signature"

Using this repository I was not able to make the queries work when oauth_token must be provided. I always get invalid signature. Tried a lot of solutions and tweaks in the code, nothing worked. Please help.
This is the code from the git mentioned:
NSString *OAuthorizationHeader(NSURL *url, NSString *method, NSData *body, NSString *_oAuthConsumerKey, NSString *_oAuthConsumerSecret, NSString *_oAuthToken, NSString *_oAuthTokenSecret)
{
NSString *_oAuthNonce = [NSString ab_GUID];
NSString *_oAuthTimestamp = [NSString stringWithFormat:#"%d", (int)[[NSDate date] timeIntervalSince1970]];
NSString *_oAuthSignatureMethod = #"HMAC-SHA1";
NSString *_oAuthVersion = #"1.0";
NSMutableDictionary *oAuthAuthorizationParameters = [NSMutableDictionary dictionary];
[oAuthAuthorizationParameters setObject:_oAuthNonce forKey:#"oauth_nonce"];
[oAuthAuthorizationParameters setObject:_oAuthTimestamp forKey:#"oauth_timestamp"];
[oAuthAuthorizationParameters setObject:_oAuthSignatureMethod forKey:#"oauth_signature_method"];
[oAuthAuthorizationParameters setObject:_oAuthVersion forKey:#"oauth_version"];
[oAuthAuthorizationParameters setObject:_oAuthConsumerKey forKey:#"oauth_consumer_key"];
if(_oAuthToken)
[oAuthAuthorizationParameters setObject:_oAuthToken forKey:#"oauth_token"];
// get query and body parameters
NSDictionary *additionalQueryParameters = [NSURL ab_parseURLQueryString:[url query]];
NSDictionary *additionalBodyParameters = nil;
if(body) {
NSString *string = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
if(string) {
additionalBodyParameters = [NSURL ab_parseURLQueryString:string];
}
}
// combine all parameters
NSMutableDictionary *parameters = [oAuthAuthorizationParameters mutableCopy];
if(additionalQueryParameters) [parameters addEntriesFromDictionary:additionalQueryParameters];
if(additionalBodyParameters) [parameters addEntriesFromDictionary:additionalBodyParameters];
// -> UTF-8 -> RFC3986
NSMutableDictionary *encodedParameters = [NSMutableDictionary dictionary];
for(NSString *key in parameters) {
NSString *value = [parameters objectForKey:key];
[encodedParameters setObject:[value ab_RFC3986EncodedString] forKey:[key ab_RFC3986EncodedString]];
}
NSArray *sortedKeys = [[encodedParameters allKeys] sortedArrayUsingFunction:SortParameter context:(__bridge void *)(encodedParameters)];
NSMutableArray *parameterArray = [NSMutableArray array];
for(NSString *key in sortedKeys) {
[parameterArray addObject:[NSString stringWithFormat:#"%#=%#", key, [encodedParameters objectForKey:key]]];
}
NSString *normalizedParameterString = [parameterArray componentsJoinedByString:#"&"];
NSLog(#"normalizedParameters: %#", normalizedParameterString);
NSString *normalizedURLString;
if ([url port] == nil) {
normalizedURLString = [NSString stringWithFormat:#"%#://%#%#", [url scheme], [url host], [url path]];
} else {
normalizedURLString = [NSString stringWithFormat:#"%#://%#:%#%#", [url scheme], [url host], [url port], [url path]];
}
NSString *signatureBaseString = [NSString stringWithFormat:#"%#&%#&%#",
[method ab_RFC3986EncodedString],
[normalizedURLString ab_RFC3986EncodedString],
[normalizedParameterString ab_RFC3986EncodedString]];
NSLog(#"signature base: %#", signatureBaseString);
NSString *key = [NSString stringWithFormat:#"%#&%#&",
[_oAuthConsumerSecret ab_RFC3986EncodedString],
[_oAuthTokenSecret ab_RFC3986EncodedString]];
NSLog(#"key codes: %#", key);
NSData *signature = HMAC_SHA1(signatureBaseString, key);
NSString *base64Signature = [signature base64EncodedString];
// PARKER CHANGE: changed oAuthAuthorizationParameters to parameters
NSMutableDictionary *authorizationHeaderDictionary = [parameters mutableCopy];
[authorizationHeaderDictionary setObject:base64Signature forKey:#"oauth_signature"];
NSMutableArray *authorizationHeaderItems = [NSMutableArray array];
for(NSString *key in authorizationHeaderDictionary) {
NSString *value = [authorizationHeaderDictionary objectForKey:key];
NSLog(#"KEY: %#", key);
NSLog(#"VALUE: %#", value);
// PARKER CHANGE: removed quotes that surrounded each value
[authorizationHeaderItems addObject:[NSString stringWithFormat:#"%#=%#",
[key ab_RFC3986EncodedString],
[value ab_RFC3986EncodedString]]];
}
// PARKER CHANGE: changed concatentation string from ", " to "&"
NSString *authorizationHeaderString = [authorizationHeaderItems componentsJoinedByString:#"&"];
// authorizationHeaderString = [NSString stringWithFormat:#"OAuth %#", authorizationHeaderString];
NSLog(#"final: %#", authorizationHeaderString);
return authorizationHeaderString;
}
And this is how I'm calling it:
- (void) makeUserRequestWithMethod:(NSString *)method
parameters:(NSDictionary *)params
completion:(void (^)(NSDictionary *data))completionBlock {
NSLog(#"%s", __func__);
NSMutableDictionary *parameters = [params mutableCopy];
[parameters addEntriesFromDictionary:[self defaultParameters]];
[parameters addEntriesFromDictionary:#{ #"method" : method }];
NSString *queryString = [self queryStringFromDictionary:parameters];
NSData *data = [NSData dataWithBytes:[queryString UTF8String] length:queryString.length];
NSString *authHeader = OAuthorizationHeader([NSURL URLWithString:FAT_SECRET_API_ENDPOINT],
#"POST",
data,
_oauthConsumerKey,
_oauthConsumerSecret,
_oAuthToken,
_oAuthTokenSecret
);
NSLog(#"header: %#", authHeader);
NSURL *url = [NSURL URLWithString:[FAT_SECRET_API_ENDPOINT stringByAppendingFormat:#"?%#", authHeader]];
[[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
id JSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
completionBlock(JSON);
} else {
completionBlock(nil);
}
}] resume];
}
I'm going to go out on a limb here and say that the code that others have proven to work is probably not at fault here, but rather first look at your own code. You say the error messages is "Invalid Signature" which sounds like it's a warning from the server you're calling, not from the code you're using.
[parameters addEntriesFromDictionary:[self defaultParameters]];
[parameters addEntriesFromDictionary:#{ #"method" : method }];
NSString *queryString = [self queryStringFromDictionary:parameters];
What happens inside [self defaultParameters] and are you 100% certain the parameters are appropriate (including spelling) for the API you're calling?
Have you verified that [self queryStringFromDictionary:parameters] prepares a properly formatting query string, and isn't introducing some error (non-escaped special characters, or percent encoding, for example)?

NSMutableArray is not instantiated as expected

I am developing a class in Objective C which contains two arrays audioFiles and files. Files array contains all the names of the audio files and audioFiles is an array to hold AVAudioFile generated from the items in files array.
I want to instantiate both the array when I create a class instance.
AudioPlayer *player = [[AudioPlayer alloc] init];
But I am unable to instantiate the audioFiles array as its showing nothing (nil). I put both the arrays in the implementation because I don't want to expose these two arrays outside of my class.
Could you please help me to fix the problem?
#import <AVFoundation/AVFoundation.h>
#import "AudioPlayer.h"
#implementation AudioPlayer
{
NSMutableArray *audioFiles;
NSArray *files;
}
- (instancetype)init
{
self = [super init];
if (self) {
files = [NSArray arrayWithObjects:#"one", #"two", #"three",#"four", nil];
[self createAudioFiles];
}
return self;
}
-(void) createAudioFiles{
for (int i = 0; i < [files count]; i++) {
NSString *audioPath = [[NSBundle mainBundle] files[i] ofType:#"wav"];
NSURL *url = [NSURL fileURLWithPath:audioPath];
AVAudioFile *file = [[AVAudioFile alloc] initForReading:url error:nil];
[audioFiles addObject:file];
}
}
#end
You are not initializing the audioFiles at all, you need to add:
audioFiles = [NSMutableArray array];
to your init or at the beginning of createAudioFiles method.
If you don't plan to add more objects after initialization, there is no need to keep the array mutable though, just declare it as NSArray *audioFiles; and change your method to:
-(void) createAudioFiles{
NSMutableArray *buffer = [NSMutableArray array];
for (int i = 0; i < [files count]; i++) {
NSString *audioPath = [[NSBundle mainBundle] files[i] ofType:#"wav"];
NSURL *url = [NSURL fileURLWithPath:audioPath];
AVAudioFile *file = [[AVAudioFile alloc] initForReading:url error:nil];
[buffer addObject:file];
}
audioFiles = [buffer copy]; // make it immutable
}

how to fetch the string starts with &abc and ends with &

i like to know how to fetch the specific string which starts with &abc and ends with &. I tried with had prefix and sufix . but this is not new line ,
&xyz;123:183:184:142&
&abc;134:534:435:432&
&qwe;323:535:234:532&
my code :
NSMutableArray *substrings = [NSMutableArray new];
NSScanner *scanner = [NSScanner scannerWithString:s];
[scanner scanUpToString:#"&abc" intoString:nil]; //
NSString *substring = nil;
[scanner scanString:#"&abc" intoString:nil]; // Scan the # character
if([scanner scanUpToString:#"&" intoString:&substring]) {
// If the space immediately followed the &, this will be skipped
[substrings addObject:substring];
NSLog(#"substring is :%#",substring);
}
// do something with substrings
[substrings release];
how to make "scanner scanUpToString:#"&abc" and count ":"==3 till "#"???? can help me
NSArray *arr = [NSArray arrayWithObjects:#"&xyz;123:183:184:142&",
#"&abc;134:534:435:432&",
#"&qwe;323:535:234:532&",
#"& I am not in it",
#"&abc I am out &" ,nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self BEGINSWITH[cd] %# AND self ENDSWITH[cd] %#",#"&abc",#"&"];
NSLog(#"Sorted Array %#",[arr filteredArrayUsingPredicate:predicate]);
NSArray *sortedArray = [arr filteredArrayUsingPredicate:predicate];
NSMutableArray *finalResult = [NSMutableArray arrayWithCapacity:0];
for(NSString *string in sortedArray)
{
NSString *content = string;
NSRange range1 = [content rangeOfString:#"&abc"];
if(range1.length > 0)
content = [content stringByReplacingCharactersInRange:range1 withString:#""];
NSRange range2 = [content rangeOfString:#"&"];
if(range2.length > 0)
content = [content stringByReplacingCharactersInRange:range2 withString:#""];
[finalResult addObject:content];
}
NSLog(#"%#",finalResult);
Try using NSRegularExpression:
- (BOOL)isValidString:(NSString *)string
{
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:#"^&abc.*&$" options:0 error:NULL];
NSTextCheckingResult *result = [regularExpression firstMatchInString:string options:0 range:NSMakeRange(0, [string length])];
return (result != nil);
}

NSArray BAD ACCESS

I'm trying to do a pickerView but I'm getting bad acess:
here is my code
-(void) viewWillAppear:(BOOL)animated {
list = [[NSArray alloc]init];
[self populateList]
}
-(void) populateList {
NSString *path = [[NSBundle mainBundle] pathForResource:#"nameoffile" ofType:#"txt"];
NSString *file = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
list = [file componentsSeparatedByString:#"\n"];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return (NSString *)[list objectAtIndex:row]; //here I'm getting bad acces
}
The error is: "Thread 1: EXC_BAD_ACCESS(code=1, address=0xa001cc65)"
NSArray returned by componentsSeparatedByString: is autoreleased value so you need to retain it.
You should remove:
list = [[NSArray alloc]init];
and add retain to:
list = [[file componentsSeparatedByString:#"\n"] retain];

Parse JSON in Objective-C with SBJSON

I just want to parse this JSON string in Objective-C using the SBJSON framework, and retrieve the three units of data:
{"x":"197","y":"191","text":"this is a string"}
How can this be done?
NSString * jsonString = #"{\"x\":\"197\",\"y\":\"191\",\"text\":\"this is a string\"}";
SBJSON *jsonParser = [[SBJSON alloc] init];
NSDictionary * dictionary = [jsonParser objectWithString:jsonString];
NSLog(#"x is %#",[dictionary objectForKey:#"x"]);
[jsonParser release];
Here's an example:
NSString *jsonText = #"...";
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *dict = [parser objectWithString:jsonText];
for (NSString *key in [#"x y text" componentsSeparatedByString:#" "]) {
NSLog(#"%# => %#", key, [dict objectForKey]);
}
Here's something similar for SBJson4Parser:
id parser = [SBJson4Parser parserWithBlock:^(id v, BOOL *stop) {
for (NSString *key in [#"x y text" componentsSeparatedByString:#" "]) {
NSLog(#"%# => %#", key, [v objectForKey]);
}
}
allowMultiRoot:NO
unwrapRootArray:NO
errorHandler:^(NSError *err) {
// handle error here
}];
NSString *jsonText = #"...";
[parser parse: [jsonText UTF8String]];