I'm not able to resume download task in NSURLSession - ios

I have create a demo for downloading a file from the server it is working fine with foreground and background, but when I'm going to resume it, It will giving below Error
I have stcuk here could help me so solved it, I search in internet but I couldn't find anything helpful.
Download file and Pause Downlaod is working fine I have issue to resume it.
Task <3AE5BF24-3A4E-4713-8FC2-A0032022C913>.<6> finished with error [-3003] Error Domain=NSURLErrorDomain Code=-3003 "(null)" UserInfo={_NSURLErrorRelatedURLSessionTaskErrorKey=(
"BackgroundDownloadTask <3AE5BF24-3A4E-4713-8FC2-A0032022C913>.<6>"
), _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundDownloadTask <3AE5BF24-3A4E-4713-8FC2-A0032022C913>.<6>}
Here is the final Xcode project
Downlaod xcode project
#import "NSURLSession+ResumeData.h"
#import <UIKit/UIKit.h>
#define IS_IOS10ORLATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10)
#pragma mark- private
static NSData * correctRequestData(NSData *data) {
if (!data) {
return nil;
}
// return the same data if it's correct
if ([NSKeyedUnarchiver unarchiveObjectWithData:data] != nil) {
return data;
}
NSMutableDictionary *archive = [[NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil] mutableCopy];
if (!archive) {
return nil;
}
NSInteger k = 0;
id objectss = archive[#"$objects"];
while ([objectss[1] objectForKey:[NSString stringWithFormat:#"$%ld",k]] != nil) {
k += 1;
}
NSInteger i = 0;
while ([archive[#"$objects"][1] objectForKey:[NSString stringWithFormat:#"__nsurlrequest_proto_prop_obj_%ld",i]] != nil) {
NSMutableArray *arr = archive[#"$objects"];
NSMutableDictionary *dic = arr[1];
id obj = [dic objectForKey:[NSString stringWithFormat:#"__nsurlrequest_proto_prop_obj_%ld",i]];
if (obj) {
[dic setValue:obj forKey:[NSString stringWithFormat:#"$%ld",i+k]];
[dic removeObjectForKey:[NSString stringWithFormat:#"__nsurlrequest_proto_prop_obj_%ld",i]];
[arr replaceObjectAtIndex:1 withObject:dic];
archive[#"$objects"] = arr;
}
i++;
}
if ([archive[#"$objects"][1] objectForKey:#"__nsurlrequest_proto_props"] != nil) {
NSMutableArray *arr = archive[#"$objects"];
NSMutableDictionary *dic = arr[1];
id obj = [dic objectForKey:#"__nsurlrequest_proto_props"];
if (obj) {
[dic setValue:obj forKey:[NSString stringWithFormat:#"$%ld",i+k]];
[dic removeObjectForKey:#"__nsurlrequest_proto_props"];
[arr replaceObjectAtIndex:1 withObject:dic];
archive[#"$objects"] = arr;
}
}
// Rectify weird "NSKeyedArchiveRootObjectKey" top key to NSKeyedArchiveRootObjectKey = "root"
if ([archive[#"$top"] objectForKey:#"NSKeyedArchiveRootObjectKey"] != nil) {
[archive[#"$top"] setObject:archive[#"$top"][#"NSKeyedArchiveRootObjectKey"] forKey: NSKeyedArchiveRootObjectKey];
[archive[#"$top"] removeObjectForKey:#"NSKeyedArchiveRootObjectKey"];
}
// Reencode archived object
NSData *result = [NSPropertyListSerialization dataWithPropertyList:archive format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
return result;
}
static NSMutableDictionary *getResumeDictionary(NSData *data) {
NSMutableDictionary *iresumeDictionary = nil;
if (IS_IOS10ORLATER) {
id root = nil;
id keyedUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
#try {
root = [keyedUnarchiver decodeTopLevelObjectForKey:#"NSKeyedArchiveRootObjectKey" error:nil];
if (root == nil) {
root = [keyedUnarchiver decodeTopLevelObjectForKey:NSKeyedArchiveRootObjectKey error:nil];
}
} #catch(NSException *exception) {
}
[keyedUnarchiver finishDecoding];
iresumeDictionary = [root mutableCopy];
}
if (iresumeDictionary == nil) {
iresumeDictionary = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil];
}
return iresumeDictionary;
}
static NSData *correctResumeData(NSData *data) {
NSString *kResumeCurrentRequest = #"NSURLSessionResumeCurrentRequest";
NSString *kResumeOriginalRequest = #"NSURLSessionResumeOriginalRequest";
if (data == nil) {
return nil;
}
NSMutableDictionary *resumeDictionary = getResumeDictionary(data);
if (resumeDictionary == nil) {
return nil;
}
resumeDictionary[kResumeCurrentRequest] = correctRequestData(resumeDictionary[kResumeCurrentRequest]);
resumeDictionary[kResumeOriginalRequest] = correctRequestData(resumeDictionary[kResumeOriginalRequest]);
NSData *result = [NSPropertyListSerialization dataWithPropertyList:resumeDictionary format:NSPropertyListXMLFormat_v1_0 options:0 error:nil];
return result;
}
#implementation NSURLSession (ResumeData)
- (NSURLSessionDownloadTask *)downloadTaskWithCorrectResumeData:(NSData *)resumeData {
NSString *kResumeCurrentRequest = #"NSURLSessionResumeCurrentRequest";
NSString *kResumeOriginalRequest = #"NSURLSessionResumeOriginalRequest";
NSData *cData = correctResumeData(resumeData);
cData = cData ? cData:resumeData;
NSURLSessionDownloadTask *task = [self downloadTaskWithResumeData:cData];
NSMutableDictionary *resumeDic = getResumeDictionary(cData);
if (resumeDic) {
if (task.originalRequest == nil) {
NSData *originalReqData = resumeDic[kResumeOriginalRequest];
NSURLRequest *originalRequest = [NSKeyedUnarchiver unarchiveObjectWithData:originalReqData ];
if (originalRequest) {
[task setValue:originalRequest forKey:#"originalRequest"];
}
}
if (task.currentRequest == nil) {
NSData *currentReqData = resumeDic[kResumeCurrentRequest];
NSURLRequest *currentRequest = [NSKeyedUnarchiver unarchiveObjectWithData:currentReqData];
if (currentRequest) {
[task setValue:currentRequest forKey:#"currentRequest"];
}
}
}
return task;
}
#end

Related

Property 'utmParametersDictionary' not found on object of type 'FIRDynamicLink *'

Semantic Issue (Xcode): Property 'utmParametersDictionary' not found on object of type 'FIRDynamicLink *'
/Users/jeremydormevil/.pub-cache/hosted/pub.dartlang.org/firebase_dynamic_links-4.1.1/ios/Classes/FLTFirebaseDynamicLinksPlugin.m:26:47
When i take a look into the code, the problem seem to came from this line :
dictionary[#"utmParameters"] = dynamicLink.utmParametersDictionary;
CODE:
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Firebase/Firebase.h>
#import <TargetConditionals.h>
#import <firebase_core/FLTFirebasePluginRegistry.h>
#import "FLTFirebaseDynamicLinksPlugin.h"
NSString *const kFLTFirebaseDynamicLinksChannelName = #"plugins.flutter.io/firebase_dynamic_links";
NSString *const kDLAppName = #"appName";
NSString *const kUrl = #"url";
NSString *const kCode = #"code";
NSString *const kMessage = #"message";
NSString *const kDynamicLinkParametersOptions = #"dynamicLinkParametersOptions";
NSString *const kDefaultAppName = #"[DEFAULT]";
static NSMutableDictionary *getDictionaryFromDynamicLink(FIRDynamicLink *dynamicLink) {
if (dynamicLink != nil) {
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
dictionary[#"link"] = dynamicLink.url.absoluteString;
NSMutableDictionary *iosData = [[NSMutableDictionary alloc] init];
if (dynamicLink.minimumAppVersion) {
iosData[#"minimumVersion"] = dynamicLink.minimumAppVersion;
}
dictionary[#"utmParameters"] = dynamicLink.utmParametersDictionary;
dictionary[#"ios"] = iosData;
return dictionary;
} else {
return nil;
}
}
static NSDictionary *getDictionaryFromNSError(NSError *error) {
NSString *code = #"unknown";
NSString *message = #"An unknown error has occurred.";
if (error == nil) {
return #{
kCode : code,
kMessage : message,
#"additionalData" : #{},
};
}
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
dictionary[kCode] = [NSString stringWithFormat:#"%d", (int)error.code];
dictionary[kMessage] = [error localizedDescription];
id additionalData = [NSMutableDictionary dictionary];
if ([error userInfo] != nil) {
additionalData = [error userInfo];
}
return #{
kCode : code,
kMessage : message,
#"additionalData" : additionalData,
};
}
#implementation FLTFirebaseDynamicLinksPlugin {
NSObject<FlutterBinaryMessenger> *_binaryMessenger;
}
#pragma mark - FlutterPlugin
- (instancetype)init:(NSObject<FlutterBinaryMessenger> *)messenger
withChannel:(FlutterMethodChannel *)channel {
self = [super init];
if (self) {
[[FLTFirebasePluginRegistry sharedInstance] registerFirebasePlugin:self];
_binaryMessenger = messenger;
_channel = channel;
}
return self;
}
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
FlutterMethodChannel *channel =
[FlutterMethodChannel methodChannelWithName:kFLTFirebaseDynamicLinksChannelName
binaryMessenger:[registrar messenger]];
FLTFirebaseDynamicLinksPlugin *instance =
[[FLTFirebaseDynamicLinksPlugin alloc] init:registrar.messenger withChannel:channel];
[registrar addMethodCallDelegate:instance channel:channel];
#if TARGET_OS_OSX
// Publish does not exist on MacOS version of FlutterPluginRegistrar.
// FlutterPluginRegistrar. (https://github.com/flutter/flutter/issues/41471)
#else
[registrar publish:instance];
[registrar addApplicationDelegate:instance];
#endif
}
- (void)cleanupWithCompletion:(void (^)(void))completion {
if (completion != nil) completion();
}
- (void)detachFromEngineForRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
[self cleanupWithCompletion:nil];
}
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
FLTFirebaseMethodCallErrorBlock errorBlock = ^(
NSString *_Nullable code, NSString *_Nullable message, NSDictionary *_Nullable details,
NSError *_Nullable error) {
if (code == nil) {
NSDictionary *errorDetails = getDictionaryFromNSError(error);
code = errorDetails[kCode];
message = errorDetails[kMessage];
details = errorDetails;
} else {
details = #{
kCode : code,
kMessage : message,
#"additionalData" : #{},
};
}
if ([#"unknown" isEqualToString:code]) {
NSLog(#"FLTFirebaseDynamicLinks: An error occurred while calling method %#, errorOrNil => %#",
call.method, [error userInfo]);
}
result([FLTFirebasePlugin createFlutterErrorFromCode:code
message:message
optionalDetails:details
andOptionalNSError:error]);
};
FLTFirebaseMethodCallResult *methodCallResult =
[FLTFirebaseMethodCallResult createWithSuccess:result andErrorBlock:errorBlock];
NSString *appName = call.arguments[kDLAppName];
if (appName != nil && ![appName isEqualToString:kDefaultAppName]) {
// TODO - document iOS default app only
NSLog(#"FLTFirebaseDynamicLinks: iOS plugin only supports the Firebase default app");
}
if ([#"FirebaseDynamicLinks#buildLink" isEqualToString:call.method]) {
[self buildLink:call.arguments withMethodCallResult:methodCallResult];
} else if ([#"FirebaseDynamicLinks#buildShortLink" isEqualToString:call.method]) {
[self buildShortLink:call.arguments withMethodCallResult:methodCallResult];
} else if ([#"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) {
[self getInitialLink:methodCallResult];
} else if ([#"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) {
[self getDynamicLink:call.arguments withMethodCallResult:methodCallResult];
} else {
result(FlutterMethodNotImplemented);
}
}
#pragma mark - Firebase Dynamic Links API
- (void)buildLink:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
FIRDynamicLinkComponents *components = [self setupParameters:arguments];
result.success([components.url absoluteString]);
}
- (void)buildShortLink:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
FIRDynamicLinkComponentsOptions *options = [self setupOptions:arguments];
NSString *longDynamicLink = arguments[#"longDynamicLink"];
if (longDynamicLink != nil) {
NSURL *url = [NSURL URLWithString:longDynamicLink];
[FIRDynamicLinkComponents
shortenURL:url
options:options
completion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
NSError *_Nullable error) {
if (error != nil) {
result.error(nil, nil, nil, error);
} else {
if (warnings == nil) {
warnings = [NSMutableArray array];
}
result.success(#{
kUrl : [shortURL absoluteString],
#"warnings" : warnings,
});
}
}];
} else {
FIRDynamicLinkComponents *components = [self setupParameters:arguments];
components.options = options;
[components
shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray<NSString *> *_Nullable warnings,
NSError *_Nullable error) {
if (error != nil) {
result.error(nil, nil, nil, error);
} else {
if (warnings == nil) {
warnings = [NSMutableArray array];
}
result.success(#{
kUrl : [shortURL absoluteString],
#"warnings" : warnings,
});
}
}];
}
}
- (void)getInitialLink:(FLTFirebaseMethodCallResult *)result {
_initiated = YES;
NSMutableDictionary *dict = getDictionaryFromDynamicLink(_initialLink);
if (dict == nil && self.initialError != nil) {
result.error(nil, nil, nil, self.initialError);
} else {
result.success(dict);
}
}
- (void)getDynamicLink:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
NSURL *shortLink = [NSURL URLWithString:arguments[kUrl]];
FIRDynamicLinkUniversalLinkHandler completion =
^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) {
if (error) {
result.error(nil, nil, nil, error);
} else {
result.success(getDictionaryFromDynamicLink(dynamicLink));
}
};
[[FIRDynamicLinks dynamicLinks] handleUniversalLink:shortLink completion:completion];
}
#pragma mark - AppDelegate
// Handle links received through your app's custom URL scheme. Called when your
// app receives a link and your app is opened for the first time after installation.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
[self checkForDynamicLink:url];
// Results of this are ORed and NO doesn't affect other delegate interceptors' result.
return NO;
}
// Handle links received as Universal Links when the app is already installed (on iOS 9 and newer).
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray *_Nullable))restorationHandler {
__block BOOL retried = NO;
void (^completionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error);
void (^__block __weak weakCompletionBlock)(FIRDynamicLink *_Nullable dynamicLink,
NSError *_Nullable error);
weakCompletionBlock = completionBlock =
^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) {
if (!error && dynamicLink && dynamicLink.url) {
[self onDeepLinkResult:dynamicLink error:nil];
}
if (!error && dynamicLink && !dynamicLink.url) {
NSLog(#"FLTFirebaseDynamicLinks: The url has not been supplied with the dynamic link."
#"Please try opening your app with the long dynamic link to see if that works");
}
// Per Apple Tech Support, a network failure could occur when returning from background on
// iOS 12. https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981
// So we'll retry the request once
if (error && !retried && [NSPOSIXErrorDomain isEqualToString:error.domain] &&
error.code == 53) {
retried = YES;
[[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL
completion:weakCompletionBlock];
}
if (error && retried) {
// Need to update any event channel the universal link failed
[self onDeepLinkResult:nil error:error];
}
};
[[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL
completion:completionBlock];
// Results of this are ORed and NO doesn't affect other delegate interceptors' result.
return NO;
}
#pragma mark - Utilities
- (void)checkForDynamicLink:(NSURL *)url {
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
if (dynamicLink) {
[self onDeepLinkResult:dynamicLink error:nil];
}
}
// Used to action events from firebase-ios-sdk custom & universal dynamic link event listeners
- (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error {
if (error) {
if (_initialLink == nil) {
// store initial error to pass back to user if getInitialLink is called
_initialError = error;
}
NSDictionary *errorDetails = getDictionaryFromNSError(error);
FlutterError *flutterError =
[FLTFirebasePlugin createFlutterErrorFromCode:errorDetails[kCode]
message:errorDetails[kMessage]
optionalDetails:errorDetails
andOptionalNSError:error];
NSLog(#"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a dynamic "
#"link: %#",
flutterError);
[_channel invokeMethod:#"FirebaseDynamicLink#onLinkError" arguments:flutterError];
} else {
NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink);
if (dictionary != nil) {
[_channel invokeMethod:#"FirebaseDynamicLink#onLinkSuccess" arguments:dictionary];
}
}
if (_initialLink == nil && dynamicLink.url != nil) {
_initialLink = dynamicLink;
}
if (dynamicLink.url != nil) {
_latestLink = dynamicLink;
}
}
- (FIRDynamicLinkComponentsOptions *)setupOptions:(NSDictionary *)arguments {
FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
NSNumber *shortDynamicLinkPathLength = arguments[#"shortLinkType"];
if (![shortDynamicLinkPathLength isEqual:[NSNull null]]) {
switch (shortDynamicLinkPathLength.intValue) {
case 0:
options.pathLength = FIRShortDynamicLinkPathLengthUnguessable;
break;
case 1:
options.pathLength = FIRShortDynamicLinkPathLengthShort;
break;
default:
break;
}
}
return options;
}
- (FIRDynamicLinkComponents *)setupParameters:(NSDictionary *)arguments {
NSURL *link = [NSURL URLWithString:arguments[#"link"]];
NSString *uriPrefix = arguments[#"uriPrefix"];
FIRDynamicLinkComponents *components = [FIRDynamicLinkComponents componentsWithLink:link
domainURIPrefix:uriPrefix];
if (![arguments[#"androidParameters"] isEqual:[NSNull null]]) {
NSDictionary *params = arguments[#"androidParameters"];
FIRDynamicLinkAndroidParameters *androidParams =
[FIRDynamicLinkAndroidParameters parametersWithPackageName:params[#"packageName"]];
NSString *fallbackUrl = params[#"fallbackUrl"];
NSNumber *minimumVersion = params[#"minimumVersion"];
if (![fallbackUrl isEqual:[NSNull null]])
androidParams.fallbackURL = [NSURL URLWithString:fallbackUrl];
if (![minimumVersion isEqual:[NSNull null]])
androidParams.minimumVersion = ((NSNumber *)minimumVersion).integerValue;
components.androidParameters = androidParams;
}
components.options = [self setupOptions:arguments];
if (![arguments[#"googleAnalyticsParameters"] isEqual:[NSNull null]]) {
NSDictionary *params = arguments[#"googleAnalyticsParameters"];
FIRDynamicLinkGoogleAnalyticsParameters *googleAnalyticsParameters =
[FIRDynamicLinkGoogleAnalyticsParameters parameters];
NSString *campaign = params[#"campaign"];
NSString *content = params[#"content"];
NSString *medium = params[#"medium"];
NSString *source = params[#"source"];
NSString *term = params[#"term"];
if (![campaign isEqual:[NSNull null]]) googleAnalyticsParameters.campaign = campaign;
if (![content isEqual:[NSNull null]]) googleAnalyticsParameters.content = content;
if (![medium isEqual:[NSNull null]]) googleAnalyticsParameters.medium = medium;
if (![source isEqual:[NSNull null]]) googleAnalyticsParameters.source = source;
if (![term isEqual:[NSNull null]]) googleAnalyticsParameters.term = term;
components.analyticsParameters = googleAnalyticsParameters;
}
if (![arguments[#"iosParameters"] isEqual:[NSNull null]]) {
NSDictionary *params = arguments[#"iosParameters"];
FIRDynamicLinkIOSParameters *iosParameters =
[FIRDynamicLinkIOSParameters parametersWithBundleID:params[#"bundleId"]];
NSString *appStoreID = params[#"appStoreId"];
NSString *customScheme = params[#"customScheme"];
NSString *fallbackURL = params[#"fallbackUrl"];
NSString *iPadBundleID = params[#"ipadBundleId"];
NSString *iPadFallbackURL = params[#"ipadFallbackUrl"];
NSString *minimumAppVersion = params[#"minimumVersion"];
if (![appStoreID isEqual:[NSNull null]]) iosParameters.appStoreID = appStoreID;
if (![customScheme isEqual:[NSNull null]]) iosParameters.customScheme = customScheme;
if (![fallbackURL isEqual:[NSNull null]])
iosParameters.fallbackURL = [NSURL URLWithString:fallbackURL];
if (![iPadBundleID isEqual:[NSNull null]]) iosParameters.iPadBundleID = iPadBundleID;
if (![iPadFallbackURL isEqual:[NSNull null]])
iosParameters.iPadFallbackURL = [NSURL URLWithString:iPadFallbackURL];
if (![minimumAppVersion isEqual:[NSNull null]])
iosParameters.minimumAppVersion = minimumAppVersion;
components.iOSParameters = iosParameters;
}
if (![arguments[#"itunesConnectAnalyticsParameters"] isEqual:[NSNull null]]) {
NSDictionary *params = arguments[#"itunesConnectAnalyticsParameters"];
FIRDynamicLinkItunesConnectAnalyticsParameters *itunesConnectAnalyticsParameters =
[FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
NSString *affiliateToken = params[#"affiliateToken"];
NSString *campaignToken = params[#"campaignToken"];
NSString *providerToken = params[#"providerToken"];
if (![affiliateToken isEqual:[NSNull null]])
itunesConnectAnalyticsParameters.affiliateToken = affiliateToken;
if (![campaignToken isEqual:[NSNull null]])
itunesConnectAnalyticsParameters.campaignToken = campaignToken;
if (![providerToken isEqual:[NSNull null]])
itunesConnectAnalyticsParameters.providerToken = providerToken;
components.iTunesConnectParameters = itunesConnectAnalyticsParameters;
}
if (![arguments[#"navigationInfoParameters"] isEqual:[NSNull null]]) {
NSDictionary *params = arguments[#"navigationInfoParameters"];
FIRDynamicLinkNavigationInfoParameters *navigationInfoParameters =
[FIRDynamicLinkNavigationInfoParameters parameters];
NSNumber *forcedRedirectEnabled = params[#"forcedRedirectEnabled"];
if (![forcedRedirectEnabled isEqual:[NSNull null]])
navigationInfoParameters.forcedRedirectEnabled = [forcedRedirectEnabled boolValue];
components.navigationInfoParameters = navigationInfoParameters;
}
if (![arguments[#"socialMetaTagParameters"] isEqual:[NSNull null]]) {
NSDictionary *params = arguments[#"socialMetaTagParameters"];
FIRDynamicLinkSocialMetaTagParameters *socialMetaTagParameters =
[FIRDynamicLinkSocialMetaTagParameters parameters];
NSString *descriptionText = params[#"description"];
NSString *imageURL = params[#"imageUrl"];
NSString *title = params[#"title"];
if (![descriptionText isEqual:[NSNull null]])
socialMetaTagParameters.descriptionText = descriptionText;
if (![imageURL isEqual:[NSNull null]])
socialMetaTagParameters.imageURL = [NSURL URLWithString:imageURL];
if (![title isEqual:[NSNull null]]) socialMetaTagParameters.title = title;
components.socialMetaTagParameters = socialMetaTagParameters;
}
return components;
}
#pragma mark - FLTFirebasePlugin
- (void)didReinitializeFirebaseCore:(void (^)(void))completion {
[self cleanupWithCompletion:completion];
}
- (NSDictionary *_Nonnull)pluginConstantsForFIRApp:(FIRApp *)firebase_app {
return #{};
}
- (NSString *_Nonnull)firebaseLibraryName {
return LIBRARY_NAME;
}
- (NSString *_Nonnull)firebaseLibraryVersion {
return LIBRARY_VERSION;
}
- (NSString *_Nonnull)flutterChannelName {
return kFLTFirebaseDynamicLinksChannelName;
}
#end
Can someone help me ? Thanks in advance.
Run pod update to get at least Firebase 7.7.0 which is when utmParametersDictionary was introduced to the API.

Is it possible to create a dispatch_async(dipatch_get_main_queue(), ^{}); with a completion go get when the dispatch block is finished?

I have a piece of code that execute a coredata update of the database, and I would like to know when that block is finished. Is there a way to get it knowing when the coredata has finished to update the tables?
Main function:
NSMutableArray* responseArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
dispatch_async(dispatch_get_main_queue(), ^{
[self parseAndAddLovAll:responseArray toArray:self.objects];
});
Function used in dispatch:
- (void)parseAndAddLovAll:(NSMutableArray*)responseArray toArray:(NSMutableArray*)destinationArray
{
NSError *error;
DB_ListOfValue_manage *elements_to_store = [[DB_ListOfValue_manage alloc] init];
NSManagedObjectContext * context = [elements_to_store managedObjectContext];
for (int index=0; index < [responseArray count]; index++)
{
NSDictionary * responseArray2 = [[NSDictionary alloc] initWithDictionary:responseArray[index]];
NSString * table_to_store = [[NSString alloc] initWithString:[responseArray2 objectForKey:#"table"]];
NSArray * lignes = [[NSArray alloc] initWithObjects:[responseArray2 objectForKey:#"lignes"], nil];
id value;
// Check if LOV table or contact table
if ((([#"Table_contact" compare:table_to_store])!=NSOrderedSame)&&
(([#"Table_event" compare:table_to_store])!=NSOrderedSame))
{
for (NSDictionary * item in lignes[0])
{
value = [item objectForKey:#"codeevent"];
if ([value isEqualToNumber:[NSNumber numberWithInt:EVENT_ID]])
{//FIXME: bug to check when SYNC
elements_to_store = (DB_ListOfValue_manage*)[NSEntityDescription insertNewObjectForEntityForName:table_to_store inManagedObjectContext:context];
elements_to_store.code_event = [value isKindOfClass:[NSNull class]] ? #"" : value;
value = [item objectForKey:#"id"];
elements_to_store.id = [value isKindOfClass:[NSNull class]] ? #"" : value;
value = [item objectForKey:#"used"];
elements_to_store.used = [value isKindOfClass:[NSNull class]] ? #"" : value;
if (![context save:&error]) {
#ifdef DEBUG
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
#endif
}
else{
#ifdef DEBUG
NSLog(#"Data saved to DB, table %# %# %#", table_to_store, elements_to_store.label1, elements_to_store.label2);
#endif
}
}
}
}
}
}

How to solve it ( EXC_BAD_ADDRESS in Objective-C )?

sometimes, fatal error occurs in my app with EXC_BAD_ADDRESS error log.
What is the cause of my code?
crash log
0. Crashed: GGMutableDictionary Isolation Queue
0 libobjc.A.dylib 0x184e2c150 objc_msgSend + 16
1 CoreFoundation 0x1862e0d04 -[NSDictionary descriptionWithLocale:indent:] + 916
2 CoreFoundation 0x1862e0dac -[NSDictionary descriptionWithLocale:indent:] + 1084
3 Foundation 0x186da35a4 _NSDescriptionWithLocaleFunc + 76
4 CoreFoundation 0x1863788bc __CFStringAppendFormatCore + 8440
5 CoreFoundation 0x18637678c _CFStringCreateWithFormatAndArgumentsAux2 + 244
6 Foundation 0x186da3418 +[NSString stringWithFormat:] + 68
7 app 0x10019f4b8 -[TinyDB saveAsync] + 4296963256
8 app 0x10019c86c __26-[TinyDB putString:value:]_block_invoke + 4296951916
9 libdispatch.dylib 0x18526e9a0 _dispatch_client_callout + 16
10 libdispatch.dylib 0x18527bee0 _dispatch_barrier_sync_f_invoke + 84
11 app 0x10019c7e0 -[TinyDB putString:value:] + 4296951776
source file
This class is used asynchronously from many other class.
This class should have thread safe. But EXC_BAD_ADDRESS fatal error occurs in saveAsync method.
I think weakDictionaryRef or isolationQueue variables are deallocated. I want to fix this problem. What should I fix in this code?
Thank you for your advice.
TinyDB.h file
#interface TinyDB : NSObject
#property (nonatomic, retain) NSString * docPath;
// #property (nonatomic, retain) NSMutableDictionary * dictionary;
#property (nonatomic, retain) NSFileManager * fileManager;
#property (nonatomic, retain) NSString * dir;
#property (nonatomic, assign) BOOL flagWrite;
- (instancetype)initWithFile:(NSString *)file;
- (NSString *)getDocPath;
- (void)putDouble:(NSString *)key value:(double)value;
- (void)putInt:(NSString *)key value:(NSInteger)value;
- (void)putMutableArray:(NSString *)key value:(NSMutableArray *)value;
- (void)putString:(NSString *)key value:(NSString *)value;
- (void)putTinyDB:(NSString *)key value:(TinyDB *)value;
- (void)putLong:(NSString *)key value:(NSInteger)value;
- (void)putBool:(NSString *)key value:(BOOL)value;
- (void)putDictionary:(NSString *)key value:(NSDictionary *)value;
- (id)get:(NSString *)key;
- (NSMutableArray *)getMutableArray:(NSString *)key;
- (BOOL)has:(NSString *)key;
- (void)saveAsync;
- (void)save;
- (NSString *)jsonString;
- (NSString *)stringify:(id)obj;
- (NSString *)getSet:(id)value;
- (NSString *)getPairSet:(NSString *)key value:(id)value;
- (NSMutableDictionary*)getMutableDictionary:(NSString*)key;
- (NSString *)getString:(NSString *)key;
- (BOOL)getBool:(NSString*)key;
- (NSArray *)allKeys;
- (void)removeObjectForKey:(NSString*)key;
#end
TinyDB.m file
#implementation TinyDB
{
#private dispatch_queue_t isolationQueue_;
#private __strong NSMutableDictionary * _myDictionary;
}
#synthesize docPath=docPath,fileManager=fileManager,dir=dir,flagWrite=flagWrite;
BOOL flagOnSave = false;
BOOL flagWrite = true;
NSString* dir;
NSString* docPath = #"";
NSLock* _dicLock=nil;
NSFileManager* fileManager;
__weak id _weakDictionaryRef;
-(id)initWithFile:(NSString *)file{
self = [super init];
docPath = file;
// ##########################################
isolationQueue_ = dispatch_queue_create([#"GGMutableDictionary Isolation Queue" UTF8String], DISPATCH_QUEUE_CONCURRENT);
// ##########################################
fileManager = [NSFileManager defaultManager];
dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) firstObject];
dir = [NSString stringWithFormat:#"%#/myapp/",dir];
BOOL flagFileExist = [fileManager fileExistsAtPath:[[NSString alloc] initWithFormat:#"%#/%#.myapp",dir,docPath]];
_myDictionary = [[NSMutableDictionary alloc] init];
if(flagFileExist){
[BSDebugger log:[NSString stringWithFormat:#"DEBUG_myapp_CONFIG : File Found!!! %# --> ",file]];
#try{
NSMutableDictionary* dic = [[NSMutableDictionary alloc] initWithContentsOfFile:[[NSString alloc] initWithFormat:#"%#/%#.myapp",dir,docPath]];
_myDictionary = [[NSMutableDictionary alloc] initWithDictionary:dic];
}#catch(NSException * e){
_myDictionary = [[NSMutableDictionary alloc] init];
}#finally{
}
}else{
[BSDebugger log:[NSString stringWithFormat:#"DEBUG_myapp_CONFIG : File Not Found!!!--> %# ",file]];
_myDictionary = [[NSMutableDictionary alloc] init];
}
_weakDictionaryRef = _myDictionary;
[self saveAsync];
return self;
}
-(void)putString:(NSString*)key value:(NSString*)value{
dispatch_barrier_sync(isolationQueue_, ^{
if(value == nil){
return;
}
#try{
[_myDictionary setObject:value forKey:key];
}#catch(NSException* e){
NSMutableDictionary* buff = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary];
_myDictionary = buff;
_weakDictionaryRef = _myDictionary;
dispatch_barrier_sync(isolationQueue_, ^{
[_myDictionary setObject:value forKey:key];
});
}#finally{
}
[self saveAsync];
});
}
- (void)putDouble:(NSString *)key value:(double)value{
dispatch_barrier_sync(isolationQueue_, ^{
[_myDictionary setObject:[[NSNumber alloc] initWithDouble:value] forKey:key];
[self saveAsync];
});
}
- (void)putInt:(NSString *)key value:(NSInteger)value{
dispatch_barrier_sync(isolationQueue_, ^{
#try{
[_myDictionary setObject:[[NSNumber alloc] initWithInteger:value] forKey:key];
}#catch(NSException* e){
NSMutableDictionary* buff = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary];
_myDictionary = buff;
_weakDictionaryRef = _myDictionary;
[_myDictionary setObject:[[NSNumber alloc] initWithInteger:value] forKey:key];
}#finally{
}
[self saveAsync];
});
}
- (void)putMutableArray:(NSString *)key value:(NSMutableArray *)value{
dispatch_barrier_sync(isolationQueue_, ^{
if( key != nil && value != nil ){
[_myDictionary setObject:value forKey:key];
[self saveAsync];
}
});
}
- (void)putTinyDB:(NSString *)key value:(TinyDB *)value{
dispatch_barrier_sync(isolationQueue_, ^{
TinyDB* db = value;
NSString* docuPath = [db getDocPath];
#try{
[_myDictionary setObject:docuPath forKey:key];
}#catch(NSException* e){
NSMutableDictionary* buff = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary];
_myDictionary = buff;
_weakDictionaryRef = _myDictionary;
dispatch_barrier_sync(isolationQueue_, ^{
[_myDictionary setObject:docuPath forKey:key];
});
}#finally{
}
[self saveAsync];
});
}
- (void)putLong:(NSString *)key value:(NSInteger)value{
dispatch_barrier_sync(isolationQueue_, ^{
[_myDictionary setObject:[[NSNumber alloc] initWithInteger:value] forKey:key];
[self saveAsync];
});
}
- (void)putBool:(NSString *)key value:(BOOL)value{
dispatch_barrier_sync(isolationQueue_, ^{
[_myDictionary setObject:[[NSNumber alloc] initWithBool:value] forKey:key];
[self saveAsync];
});
}
- (void)putDictionary:(NSString *)key value:(NSDictionary *)value{
dispatch_barrier_sync(isolationQueue_, ^{
[_myDictionary setObject:value forKey:key];
[self saveAsync];
});
}
-(void)removeObjectForKey:(NSString*)key{
dispatch_barrier_sync(isolationQueue_, ^{
if( _myDictionary != nil && [_myDictionary objectForKey:key] != nil ){
[_myDictionary removeObjectForKey:key];
}
});
}
-(void) save{
dispatch_barrier_sync(isolationQueue_, ^{
#try {
// NSLog([NSString stringWithFormat:#"writeToFile Error : orgPath = %#/%#.myapp / %#",dir,docPath, self.dictionary ]);
// NSMutableDictionary* nsDic = self.dictionary;
if( _myDictionary != nil ){
NSDictionary * _dictionary =
(__bridge NSDictionary *)(CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
(__bridge CFPropertyListRef)(_myDictionary),
kCFPropertyListImmutable));
if( _dictionary != nil ){
[_dictionary writeToFile:[[NSString alloc] initWithFormat:#"%#/%#.myapp",dir,docPath] atomically: false];
}
}
}#catch (NSException *exception) {
_myDictionary = [[NSMutableDictionary alloc] initWithDictionary:_myDictionary];
_weakDictionaryRef = _myDictionary;
}#finally {
}
});
}
// ################################################################
// normal function
- (NSString *)jsonString{
__block NSString* buff = #"";
dispatch_barrier_sync(isolationQueue_, ^{
if( _myDictionary != nil ){
NSDictionary * _dictionary = nil;
// dispatch_barrier_sync(isolationQueue_, ^{
_dictionary = (__bridge NSDictionary *)(CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
(__bridge CFPropertyListRef)(_myDictionary),
kCFPropertyListImmutable));
if( _dictionary != nil ){
buff = [self stringify:_dictionary];
}
}else{
NSLog(#"buff = [self stringify:_myDictionary]; is nil ");
}
});
return buff;
}
- (NSString *)stringify:(id)obj{
if([obj isKindOfClass:[NSDictionary class]]){
int idx = 0;
NSString* buff = #"{";
if( obj != nil ){
NSDictionary* dic = [NSDictionary dictionaryWithDictionary:obj]; //obj;
for(NSString* key in dic){
id value = [dic objectForKey:key];
if(idx != 0){
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,#","];
}
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,[self getPairSet:key value:value]];
idx++;
}
}
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,#"}"];
return buff;
}else if([obj isKindOfClass:[NSArray class]]){
int idx = 0;
NSString* buff = #"[";
if( obj != nil ){
NSMutableArray* _a = [[NSMutableArray alloc] init];
for( int ai = 0; ai < [obj count]; ai++){
if( [obj objectAtIndex:ai] != nil ){
[_a addObject:[obj objectAtIndex:ai]];
}
}
NSArray* arr = [NSArray arrayWithArray:_a]; //obj;
for(id value in arr){
if(idx != 0){
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,#","];
}
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,[self getSet:value]];
idx++;
}
}
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,#"]"];
return buff;
}else{
return [self getSet:obj];
}
}
- (NSString *)getSet:(id)value{
NSString* buff = #"";
if([value isKindOfClass:[NSString class]]){
buff = [[NSString alloc] initWithFormat:#"%#\"%#\"",buff,value];
}else if([value isKindOfClass:[NSNumber class]]){
NSNumber* val = value;
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,[val stringValue]];
}else{
buff = [[NSString alloc] initWithFormat:#"%#%#",buff,[self stringify:value]];
}
return buff;
}
- (NSString *)getPairSet:(NSString *)key value:(id)value{
NSString* buff = #"";
if([value isKindOfClass:[NSString class]]){
buff = [[NSString alloc] initWithFormat:#"%#\"%#\":\"%#\"",buff,key,value];
}else if([value isKindOfClass:[NSNumber class]]){
buff = [[NSString alloc] initWithFormat:#"%#\"%#\":%#",buff,key,[value stringValue]];
}else{
buff = [[NSString alloc] initWithFormat:#"%#\"%#\":%#",buff,key,[self stringify:value]];
}
return buff;
}
-(NSMutableDictionary*)getMutableDictionary:(NSString*)key{
NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
id obj = [_myDictionary objectForKey:key];
if(obj != nil){
dic = [[NSMutableDictionary alloc] initWithDictionary:obj];
}
return dic;
}
-(NSArray *)allKeys{
__block NSArray* arr = nil;
dispatch_barrier_sync(isolationQueue_, ^{
if( _myDictionary != nil ){
arr = [_myDictionary allKeys];
}
});
return arr;
}
- (NSString *)getDocPath{
return docPath;
}
- (id)get:(NSString *)key{
__block id _obj = nil;
dispatch_barrier_sync(isolationQueue_, ^{
_obj = [_myDictionary objectForKey:key];
});
return _obj;
}
- (NSString *)getString:(NSString *)key{
__block NSString* returnStr = #"";
dispatch_barrier_sync(isolationQueue_, ^{
if([_myDictionary objectForKey:key]==nil){
returnStr = #"";
}
if([[_myDictionary objectForKey:key] isKindOfClass:[NSString class]]){
returnStr = [_myDictionary objectForKey:key];
}else{
returnStr = #"";
}
});
return returnStr;
}
- (BOOL)getBool:(NSString*)key{
__block BOOL flag = false;
dispatch_barrier_sync(isolationQueue_, ^{
if([_myDictionary objectForKey:key]==nil){
flag = NO;
}
if([[_myDictionary objectForKey:key] isKindOfClass:[NSNumber class]]){
NSNumber* boolValue = [_myDictionary objectForKey:key];
if([boolValue boolValue] == YES){
flag = YES;
}else{
flag = NO;
}
}else{
flag = NO;
}
});
return flag;
}
- (NSMutableArray *)getMutableArray:(NSString *)key{
__block NSMutableArray* _arr = nil;
dispatch_barrier_sync(isolationQueue_, ^{
_arr = [_myDictionary objectForKey:key];
});
return _arr;
}
- (BOOL)has:(NSString *)key{
__block BOOL flag = false;
dispatch_barrier_sync(isolationQueue_, ^{
if([_myDictionary objectForKey:key] != nil){
flag = true;
}else{
flag = false;
}
});
return flag;
}
// #########################
// save function
int flagTest = 0;
bool mark = 0;
NSTimer* saveTimer = nil;
-(void)saveAsync{
#try {
[BSDebugger log:[NSString stringWithFormat:#"_weakDictionaryRef : %# ",_weakDictionaryRef ]];
if( _myDictionary != nil ){
if( _weakDictionaryRef != nil ){
NSDictionary * _dictionary = nil;
_dictionary = (__bridge NSDictionary *)(CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
(__bridge CFPropertyListRef)(_myDictionary),
kCFPropertyListImmutable));
#try{
flagOnSave = true;
UIBackgroundTaskIdentifier taskID = [myappCore beginBackgroundUpdateTask];
flagWrite = false;
NSString* orgPath = [[NSString alloc] initWithFormat:#"%#/%#.myapp",dir,docPath ];
#try {
if( _dictionary != nil ){
[_dictionary writeToFile:orgPath atomically:YES];
}
}#catch (NSException *exception) {
[BSDebugger log:[NSString stringWithFormat:#"DEBUG_myapp_TINYDB : %#",[exception callStackSymbols]]];
}#finally {
}
flagWrite = true;
flagOnSave = false;
[myappCore endBackgroundUpdateTask:taskID];
}#catch (NSException *exceptionMain) {
[BSDebugger log:[NSString stringWithFormat:#"DEBUG_myapp_TINYDB : %#",[exceptionMain callStackSymbols]]];
}#finally {
_dictionary = nil;
}
return;
// });
}
}
}#catch (NSException *exception) {
}#finally {
// [_dicLock unlock];
}
}
#end
Some ideas:
Turn on zombies (How to enable NSZombie in Xcode). You'll get more information about the object causing the crash when you do that.
If you can make the error happen at will, set a breakpoint at the top of saveAsync and step through it.
Change the stringWithFormat calls somehow so they don't reference anything that might be deallocated and see if the problem goes away. If it does, you'll know what was causing it.
I find it sometimes helps to override retain and release in objects I'm suspicious of and either print something out or set a breakpoint so I can see who might be over-releasing an object.

data disappear out of UNIUrlConnection

What I'm trying to do is to pass data from my Objective-C to my swift file.
Recently, when I have successfully connected my objective c file with my swift file, I can print data that get from UNIUrlConnection(which means the connection between swift and objective-c works fine).
Then I create a NSMutableDictionary object and add those data into NSMutableDictionary. I want to pass this NSMutableDictionary object to my swift file so that I can output them on my viewController.
However, the NSMutableDictionary contains correct data within the UNIUrlConnection but then contains none out of UNIUrlConnection. Thus the NSMutableDictionary passed to swift file would always contain no data. How can I solve this?
This is my objective c file.
#import <Foundation/Foundation.h>
#import <UNIRest.h>
#import "findByIngredients.h"
#implementation findByIngredients
-(NSMutableDictionary*) connectAPI:(NSString*) ingredients Number:(NSString*) number{
NSMutableDictionary *temp = [NSMutableDictionary dictionaryWithCapacity:10];
NSString* url = #"https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/findByIngredients?fillIngredients=false";
if (![ingredients isEqual: #""]) {
NSString* ingre = #"&ingredients=";
ingre = [ingre stringByAppendingString:ingredients];
url = [url stringByAppendingString:ingre];
}
else {
NSString* ingre = #"&ingredients=<required>";
url = [url stringByAppendingString:ingre];
}
NSString* LL = #"&limitLicense=false";
url = [url stringByAppendingString:LL];
if (![number isEqual: #""]) {
NSString* numberOfReturn = #"&number=";
numberOfReturn = [numberOfReturn stringByAppendingString:number];
url = [url stringByAppendingString:numberOfReturn];
}
NSString* ranking = #"&ranking=1";
url = [url stringByAppendingString:ranking];
// These code snippets use an open-source library. http://unirest.io/objective-c
NSDictionary *headers = #{#"X-Mashape-Key": #"KEY", #"Accept": #"application/json"};
UNIUrlConnection *asyncConnection = [[UNIRest get:^(UNISimpleRequest *request) {
[request setUrl:url];
[request setHeaders:headers];
}] asJsonAsync:^(UNIHTTPJsonResponse *response, NSError *error) {
NSInteger code = response.code;
NSDictionary *responseHeaders = response.headers;
UNIJsonNode *body = response.body;
NSData *rawBody = response.rawBody;
if (rawBody) {
id allKeys = [NSJSONSerialization JSONObjectWithData:rawBody options:0 error:&error];
for (int i=0; i<[allKeys count]; i++) {
NSDictionary *arrayResult = [allKeys objectAtIndex:i];
// NSString* myNewString = [NSString stringWithFormat:#"%d", i];
NSString *key = [arrayResult objectForKey:#"id"];
NSString *value = [arrayResult objectForKey:#"title"];
[temp setObject:value forKey:key];
NSLog(#"id=%#",[arrayResult objectForKey:#"id"]);
NSLog(#"title=%#",[arrayResult objectForKey:#"title"]);
}
}
int size = [temp count];
NSLog(#"temp size is %d",size);
NSLog(#"successfully test API");
}];
// int size = [temp count];
// NSLog(#"temp size is %d",size);
return temp;
}
#end
Here the size of temp within UNIUrlConnection is correct. But if I put the size before return (which I comment out), it shows 0, which is wrong.
This is my swift file.
#IBAction func search(_ sender: Any) {
let ingreArr = IngredientsText.text.components(separatedBy: [",", " "])
var ingre:String = ingreArr[0]
let sep:String = "%2C"
for (index,element) in ingreArr.enumerated() {
if (index >= 1) {
ingre = ingre + sep + element
}
}
let test = findByIngredients()
// test.connectAPI(ingre, number: NumberOfResults.text)
let result: Dictionary = test.connectAPI(ingre, number: NumberOfResults.text) as Dictionary
let num:Int = result.count
print(num)
}
The num is 0.

iOS How to reload tableview reload data of parsing array?

I am newbie in iOS and i have an issue i parsed an array and show in table which having three sections and every each section i added new row to add up its all children in hierarchy but due to table reload issue its indexing change and show wrong results. here is my code below
+ (void)getTypesWith:(void (^)(NSArray *, NSError *))completionHandler
{
[ZNetworkManager postDataForBackGround:nil atURL:[ZMappingManager getRequestURLToGetPropertiesTypes] completionHandler:^(NSArray *array, NSError *error)
{
NSMutableArray *typesDictionariesArray =[NSMutableArray array];
NSMutableDictionary* details = [NSMutableDictionary dictionary];
if (!error)
{
NSDictionary *fetchedDictionary = (NSDictionary *) array;
if([fetchedDictionary isKindOfClass:[NSDictionary class]] == NO)
{
[details setValue:#"Fetched dictionary is null" forKey:#"desription"];
completionHandler(nil ,[NSError errorWithDomain:#"MyDomain" code:1 userInfo:details]);
}
else
{
if([[[fetchedDictionary objectForKey:#"meta"] objectForKey:#"status"] isEqualToString:#"200"]){
NSDictionary *data = [fetchedDictionary objectForKey:#"response"];
if([data isKindOfClass:[NSDictionary class]] == NO)
{
[details setValue:#"Fetched dictionary is null" forKey:#"desription"];
completionHandler(nil ,[NSError errorWithDomain:#"MyDomain" code:1 userInfo:details]);
}
else
{
NSArray *allTypes = [data objectForKey:#"type"];
if([allTypes count] == 0)
{
[details setValue:#"Fetched dictionary is null" forKey:#"desription"];
completionHandler(nil ,[NSError errorWithDomain:#"MyDomain" code:1 userInfo:details]);
}
else
{
NSMutableArray *searchTypes = [[NSMutableArray alloc] init];
for (int i=0; i<[allTypes count]; i++)
// for (NSDictionary *typeDic in allTypes)
{
NSDictionary *typeDic = [allTypes objectAtIndex:i];
[typesDictionariesArray addObject:typeDic];
ZZameenType *newType = [[ZZameenType alloc] init];
[newType loadFromDictionary:typeDic];
[searchTypes addObject:newType];
NSArray *arrayforChild = [typeDic objectForKey:#"childs"];
for (int j=0; j<[arrayforChild count]; j++)
// for(NSDictionary *typeChild in arrayforChild)
{
NSDictionary *typeChild = [arrayforChild objectAtIndex:j];
ZZameenType *newChild;
[typesDictionariesArray addObject:typeChild];
newChild = [[ZZameenType alloc] init];
[newChild loadFromDictionary:typeChild];
[searchTypes addObject:newChild];
if(j == 0)
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSString *combineString = [NSString stringWithFormat:#"All %#",[typeDic objectForKey:#"title_alt2"]];
[dict setObject:combineString forKey:#"title"];
[dict setObject:combineString forKey:#"title_alt2"];
[dict setObject:combineString forKey:#"title_alt1"];
[dict setObject:[typeDic objectForKey:#"type_id"] forKey:#"parent_id"];
[dict setObject:[typeDic objectForKey:#"child_list"] forKey:#"type_id"];
[typesDictionariesArray insertObject:dict atIndex:[typesDictionariesArray count]-1];
newChild = [[ZZameenType alloc] init];
[newChild loadFromDictionary:dict];
[searchTypes insertObject:newChild atIndex:[searchTypes count]-1];
}
}
newType = nil;
}
NSSortDescriptor *typeID_sort = [NSSortDescriptor sortDescriptorWithKey:#"type_id" ascending:YES];
[searchTypes sortUsingDescriptors:[NSArray arrayWithObjects:typeID_sort,nil]];
[ZGlobals saveSearchTypes:typesDictionariesArray];
completionHandler(searchTypes ,nil);
searchTypes = nil;
details = nil;
}
}
}else{
}
}
}
}];
}
cellForRowAtIndexPath
if(selectionC == nil) {
selectionC=[[[NSBundle mainBundle] loadNibNamed:#"SelectionCell" owner:self options:nil] objectAtIndex:0];
}
KLog(#"view frame is %#",NSStringFromCGRect(self.frame));
KLog(#"table frame is %#",NSStringFromCGRect(tableView.frame));
NSArray *values =[[ZGlobals getPropertTypeSectionsValues] objectAtIndex:indexPath.section];
ZZameenType *type =[values objectAtIndex:indexPath.row];
selectionC.selectionTitle.text = type.title;
selectionC.selectionTitle.textColor = [ZTheme cellValuesColorIPAD];

Resources