iOS NSMutableData *data = [[NSMutableData alloc] init]; crashes - objective-c

I m using below mentioned line in a function
NSMutableData *data = [[NSMutableData alloc] init];
And I m calling this function a no of time (e.g. 100 times). So my problem is that initially for about 60 times or more it is working properly but after that it gives me "BAD_EXC_ACCESS"
Function is given below
+ (NSString *) recvToFile:(NSString *)_fileName {
#try {
int _sz = [self recvNumber:4];
uint8_t t[_sz];
NSMutableData *data = [[NSMutableData alloc] init];
NSMutableData *fileData = [[NSMutableData alloc] init];
long _pos = 0;
NSString *_fullPath = _fileName;
while (_sz > _pos) {
long _c = [m_sin read:t maxLength:_sz];
_pos += _c;
data = [NSData dataWithBytes:t length:_c];
if([Misc checkFileExists:_fileName]==nil)
[[NSFileManager defaultManager] createFileAtPath:_fullPath contents:nil attributes:nil];
[fileData appendData:data];
}
[fileData writeToFile:_fullPath atomically:YES];
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:_fullPath error:nil];
long long length = [[attr valueForKey:#"NSFileSize"] intValue];
if (length >= _sz)
return (_fullPath);
}
#catch (NSException * e) {
}
return (nil);
}
And I m calling this function every time i receive a file. I want to save file from bytes

You should not initialize data here:
NSMutableData *data = [[NSMutableData alloc] init];
just initialize the variable to nil;
NSMutableData* data = nil;

Try adding data like this to nsmutabledata
[data appendBytes:t length:_c];

Related

Check auto-renewable subscription expire date from validate receipt

I am calling receipt validation method in app delegate to check the renewable process. Its working fine in development mode but after releasing from app store its always returning yes, even though user have not purchase the product. Please Suggest what wrong I am doing. In sandbox mode its working fine but after release I found the issue that its always returning true. For validating receipt I am using below code
// Validate the receipt
+(BOOL ) getStoreReceipt:(BOOL)sandbox andTrasaction:(SKPaymentTransaction *)tractaion{
NSArray *objects;
NSArray *keys;
NSDictionary *dictionary;
BOOL gotreceipt = false;
#try {
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
NSString *receiptString = [self base64forData:receiptData];
NSLog(#"receiptString Value---->= %#",receiptString);
NSString *encReceipt = [receiptData base64EncodedStringWithOptions:0];
NSLog(#"receiptString Value ======>= %#",encReceipt);
if (receiptString != nil) {
NSString *strSharedSecrect = #"MY_Secrect_Key";
objects = [[NSArray alloc] initWithObjects:receiptString,strSharedSecrect, nil];
keys = [[NSArray alloc] initWithObjects:#"receipt-data",#"password", nil];
dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
NSString *postData = [self getJsonStringFromDictionary:dictionary];
NSLog(#"postData Value---->= %#",receiptString);
NSString *urlSting = #"https://buy.itunes.apple.com/verifyReceipt";
// if (sandbox) urlSting = #"https://sandbox.itunes.apple.com/verifyReceipt";
dictionary = [self getJsonDictionaryWithPostFromUrlString:urlSting andDataString:postData];
NSLog(#"dictionary Value for receipt---->= %#",dictionary);
if ([dictionary objectForKey:#"status"] != nil) {
if ([[dictionary objectForKey:#"status"] intValue] == 0) {
gotreceipt = true;
}
}
}
}//623065
} #catch (NSException * e) {
gotreceipt = false;
return NO;
NSLog(#"NSException---->= %#",e);
}
if (!gotreceipt) {
NSLog(#"Not gotreceipt---->=");
objects = [[NSArray alloc] initWithObjects:#"-1", nil];
keys = [[NSArray alloc] initWithObjects:#"status", nil];
dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
return NO;
}else{
BOOL isPurchased = [self PurchasedSubscriptionStatues:dictionary];
return isPurchased;
}
return NO;
}
Checking if pending for renewable is there or not...
+(BOOL)PurchasedSubscriptionStatues:(NSDictionary *)transactionReceipt
{
if ([[transactionReceipt allKeys] containsObject:#"pending_renewal_info"]) {
NSArray *arrData = [transactionReceipt objectForKey:#"pending_renewal_info"];
NSDictionary *dicPendinRenew = [arrData objectAtIndex:0];
if ([[dicPendinRenew allKeys] containsObject:#"expiration_intent"] || [[dicPendinRenew objectForKey:#"auto_renew_status"] integerValue]==0) {
return NO;
}else if ([[dicPendinRenew objectForKey:#"auto_renew_status"] integerValue]==1) {
return YES;
}else{
return NO;
}
}else{
return YES;
}
return NO;
}
Convert String To Dictionary
+(NSString *)getJsonStringFromDictionary:(NSDictionary *)dicVal
{
NSError *error = nil;
NSData *postData = [NSJSONSerialization dataWithJSONObject:dicVal options:NSJSONWritingPrettyPrinted error:&error];
NSString *postString = #"";
if (! postData) {
NSLog(#"Got an error: %#", error);
return nil;
}
else { postString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
return postString;
}
}
Convert Dictionary to string
+(NSDictionary *) getJsonDictionaryWithPostFromUrlString:(NSString *)urlString andDataString:(NSString *)dataString {
NSString *jsonString = [self getStringWithPostFromUrlString:urlString andDataString:dataString];
NSLog(#"getJsonDictionaryWithPostFromUrlString-->%#", jsonString); // see what the response looks like
return [self getDictionaryFromJsonString:jsonString];
}
+ (NSDictionary *) getDictionaryFromJsonString:(NSString *)jsonstring {
NSError *jsonError;
NSDictionary *dictionary = (NSDictionary *) [NSJSONSerialization JSONObjectWithData:[jsonstring dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jsonError];
if (jsonError) {
dictionary = [[NSDictionary alloc] init];
}
return dictionary;
}
//Request for post method to get the recipt
+ (NSString *) getStringWithPostFromUrlString:(NSString *)urlString andDataString:(NSString *)dataString {
NSString *s = #"";
#try {
NSData *postdata = [dataString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postlength = [NSString stringWithFormat:#"%d", [postdata length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setTimeoutInterval:60];
[request setHTTPMethod:#"POST"];
[request setValue:postlength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postdata];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if (data != nil) {
s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
}
#catch (NSException *exception) {
s = #"";
}
return s;
}
// from https://stackoverflow.com/questions/2197362/converting-nsdata-to-base64
+ (NSString*)base64forData:(NSData*)theData {
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
------------------------------------------------------------------------
I think your PurchasedSubscriptionStatues method has an error: if the receipt does not contain pending_renewal_info key, it returns YES. Try creating a new sandbox user and see if the receipt contains this key, if not - then this method should return NO in such case.
Also, you can try using some library that can manage InApp purchases, like RMStore, to ease on the receipt verification.

Address to coordinate in objective c in google map

I have 60 address and I want to add the pin for every address. I want to use google maps and not Apple maps. I have a loop outside, and calling this method for 100 elements.
And some times I got this error: *** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array
And the error is not regular, I mean the error does not corresponds to an exact address. Sometimes I got 20 errors, sometimes 15,...
Does anyone know how to resolve it?
thank you
- (CLLocationCoordinate2D) getLocationFromAddress:(NSString*) address
{
NSError *error = nil;
NSString *lookUpString;
NSDictionary *jsonDict;
NSData *jsonResponse;
NSArray *locationArray;
lookUpString = [[NSString alloc] initWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=true", address];
lookUpString = [lookUpString stringByReplacingOccurrencesOfString:#" " withString:#"+"];
jsonResponse = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:lookUpString]];
jsonDict = [NSJSONSerialization JSONObjectWithData:jsonResponse options:kNilOptions error:&error];
locationArray = [[NSArray alloc] init];
locationArray = [[[jsonDict valueForKey:#"results"] valueForKey:#"geometry"] valueForKey:#"location"];
#try {
locationArray = [locationArray objectAtIndex:0];
NSLog(#" LOADING, %d, %d, %d", [locationArray count], [jsonDict count], [jsonResponse length]);
}
#catch (NSException *exception) {
NSLog(#"ERROR LOADING, %d, %d, %d", [locationArray count], [jsonDict count], [jsonResponse length]);
}
#finally {
}
NSString *latitudeString = [[NSString alloc] init];
latitudeString = [locationArray valueForKey:#"lat"];
NSString *longitudeString = [[NSString alloc] init];
longitudeString = [locationArray valueForKey:#"lng"];
NSString *statusString = [[NSString alloc] init];
statusString = [jsonDict valueForKey:#"status"];
double latitude = 0.0;
double longitude = 0.0;
if ([statusString isEqualToString:#"OK"])
{
latitude = [latitudeString doubleValue];
longitude = [longitudeString doubleValue];
}
else
NSLog(#"Something went wrong, couldn't find address");
_location.longitude = longitude;
_location.latitude = latitude;
return _location;
}

Memory leak using ARC in NSData framework

i can't figure out one memory leak. I will add screen shot with code and marked line where this happens.
Maybe some could help me and take a look.
Thanks.
- (AVAudioPlayer*)getSpeachSoundObject{
NSString *objectIDString = [NSString stringWithFormat:#"%i", jmObject.objectID];
NSString * __weak textPlaySource = [DataController getMediaUrlStringForObjectID:objectIDString parentType:PARENT_TYPE_ITEM_AUDIO];
NSError * error = nil ;
if (textPlaySource) {
//NSURL *soundURL = [[NSURL alloc] initFileURLWithPath:textPlaySource];//[NSURL fileURLWithPath:textPlaySource];
NSData * data = [NSData dataWithContentsOfFile:textPlaySource options:NSDataReadingMapped error:&error ] ;
textPlaySource = nil;
NSError *error;
//speechSound = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
AVAudioPlayer *lspeechSound = data ? [[AVAudioPlayer alloc] initWithData:data error:&error ] : nil ;
data = nil;
if (error) {
WLog([NSString stringWithFormat:#"Error creating sound file:%#", error]);
}
return lspeechSound;
//soundURL = nil;
}
return nil;
}

objective c - convert mpmediaitem to ogg vorbis

i found (customizing a method i found) a way to convert a MpMediaItem and to obtain a mp3 file. Probably it's not the best way but it's working.
Is there a way to obtain an *.ogg file instead of *.mp3 ? What would be the proper approach?
This is the method i use to get the *.mp3 file:
-(void)exportMP3:(NSURL*)url toFileUrl:(NSString*)fileURL
{
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetReader *reader=[[AVAssetReader alloc] initWithAsset:asset error:nil];
NSMutableArray *myOutputs =[[NSMutableArray alloc] init];
for(id track in [asset tracks])
{
AVAssetReaderTrackOutput *output=[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:nil];
[myOutputs addObject:output];
[reader addOutput:output];
}
[reader startReading];
NSFileHandle *fileHandle ;
NSFileManager *fm=[NSFileManager defaultManager];
if(![fm fileExistsAtPath:fileURL])
{
[fm createFileAtPath:fileURL contents:[[NSData alloc] init] attributes:nil];
}else{
NSURL *url = [NSURL URLWithString:fileURL];
[fm removeItemAtURL:url error:nil];
[fm createFileAtPath:fileURL contents:[[NSData alloc] init] attributes:nil];
}
fileHandle=[NSFileHandle fileHandleForWritingAtPath:fileURL];
[fileHandle seekToEndOfFile];
AVAssetReaderOutput *output=[myOutputs objectAtIndex:0];
int totalBuff=0;
int test = 1;
while(test == 1)
{
CMSampleBufferRef ref=[output copyNextSampleBuffer];
if(ref==NULL)
test = 0;
if(ref==NULL)
break;
//copy data to file
//read next one
AudioBufferList audioBufferList;
NSMutableData *data;
CMBlockBufferRef blockBuffer;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(ref, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);
for( int y=0; y<audioBufferList.mNumberBuffers; y++ )
{
AudioBuffer audioBuffer = audioBufferList.mBuffers[y];
void *frame = audioBuffer.mData;
data = [[NSMutableData alloc] initWithBytes:frame length:audioBuffer.mDataByteSize];
}
totalBuff++;
NSLog(#"\n%d\n",totalBuff);
int time = [self.mediaPlayer durationOfCurrentItem];
if (totalBuff * 2 <= time + 1)
[fileHandle writeData:data];
}
[fileHandle closeFile];
}
You can use libvorbis to encode PCM data to Vorbis.

AFNetworking HTTPRequestOperation need to set array from completion block but this isn't working?

I'm using AFNetworking with AFHTTPRequestOperation to pull XML data from a webservice. This is working fine and im getting the data I need but I need to split this data into objects and initialize a NSMutableArray with this data. This is working in the completion block, but just before I return the array in my method the data is gone? How do I do this?
Here is some of my code:
NSMutableArray *result = [[NSMutableArray alloc] init];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString* response = [operation responseString];
NSData* xmlData = [response dataUsingEncoding:NSUTF8StringEncoding];
NSError *xmlError;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&xmlError];
NSArray *allElements = [doc.rootElement elementsForName:#"Misc"];
for (GDataXMLElement *current in allElements)
{
NSString *titel;
NSString *tekst;
NSArray *titels = [current elementsForName:#"Titel"];
if(titels.count > 0)
{
GDataXMLElement *firstTitel = (GDataXMLElement *) [titels objectAtIndex:0];
titel = firstTitel.stringValue;
} else continue;
NSArray *teksts = [current elementsForName:#"Tekst"];
if(teksts.count > 0)
{
GDataXMLElement *firstTekst = (GDataXMLElement *) [teksts objectAtIndex:0];
tekst = firstTekst.stringValue;
} else continue;
HVMGUniversalItem *item = [[HVMGUniversalItem alloc] initWithTitel:titel AndTekst:tekst];
[result addObject:item];
}
NSLog(#"%i", result.count);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [operation error]);
}];
[operation start];
NSLog(#"%i", result.count);
return result;
What am I doing wrong? Why isn't the data present in the array when returning?
Why isn't the data present in the array when returning?
Because AFNetworking use an async pattern. So the return code will be performed before the operation will be completed.
You need to use a different approach or follow Can AFNetworking return data synchronously (inside a block)?. The latter is discouraged.
A solution could be to:
-> Create a NSOperationQueue within your class that will include your operation. Create it as a property for your class like.
#property (nonatomic, strong, readonly) NSOperationQueue* downloadQueue;
- (NSOperationQueue*)downloadQueue
{
if(downloadQueue) return downloadQueue;
downloadQueue = // alloc init here
}
-> Create a property for your array (synthesize also it)
#property (nonatomic, strong) NSMutableArray* result;
-> Wrap your code within a specific method like doOperation.
self.result = [[NSMutableArray alloc] init];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
__weak YourClass* selfBlock = self;
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString* response = [operation responseString];
NSData* xmlData = [response dataUsingEncoding:NSUTF8StringEncoding];
NSError *xmlError;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&xmlError];
NSArray *allElements = [doc.rootElement elementsForName:#"Misc"];
for (GDataXMLElement *current in allElements)
{
NSString *titel;
NSString *tekst;
NSArray *titels = [current elementsForName:#"Titel"];
if(titels.count > 0)
{
GDataXMLElement *firstTitel = (GDataXMLElement *) [titels objectAtIndex:0];
titel = firstTitel.stringValue;
} else continue;
NSArray *teksts = [current elementsForName:#"Tekst"];
if(teksts.count > 0)
{
GDataXMLElement *firstTekst = (GDataXMLElement *) [teksts objectAtIndex:0];
tekst = firstTekst.stringValue;
} else continue;
HVMGUniversalItem *item = [[HVMGUniversalItem alloc] initWithTitel:titel AndTekst:tekst];
[selfBlock.result addObject:item];
}
NSLog(#"%i", result.count);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [operation error]);
}];
[downloadQueue addOperation:operation];
-> if you need to notify that result has object send a notification, use the delegate pattern, etc...
Hope that helps.