I'm calling this method:
- (void)allServerListsWithCompletion:(void(^_Nullable)(NSArray<VPNUServerItem *> *_Nullable allServerItems,
NSArray<VPNUServerItem *> *_Nullable streamServerItems,
NSArray<VPNUServerItem *> *_Nullable personalServerItems,
NSArray<VPNUServerItem *> *_Nullable optimalServerItems,
NSError *_Nullable error))completion;
And doing this:
[KSVPNUFacade.defaultFacade allServerListsWithCompletion:^(NSArray *allServerItems,
NSArray *streamServerItems,
NSArray *personalServerItems,
NSArray *optimalServerItems,
NSError *error) {
}];
But every time the method allServerListsWithCompletion is called, I get the error:
allServerListsWithCompletion:]: unrecognized selector sent to instance
0x280e87000
How can I fix it? That's the exactly line where I'm getting the error
Related
I have this method:
- (void)shareItems:(NSArray *)shareItems fromViewController:(UIViewController *)viewController anchorView:(UIView *)anchorView completion:(void (^)(NSString *activityType, BOOL, NSError *))completionHandler;
I'm simply trying to implement it in XCode 7.0.1 and I'm getting the following error messages:
If you can't see, I tried to implement:
[[VMSocialShareManager defaultManager] shareItems:shareItems fromViewController:self anchorView:shareCell completion:^(NSString *activityType, BOOL completed, NSError *error) {
...
}];
But get the error:
Incompatible block pointer types sending 'void (^)(NSString *__strong, BOOL, NSError *__strong)' to parameter of type 'void (^)(BOOL, NSString *__strong, NSError *__strong)'
OK, sure, I'll try to flip the BOOL and the NSString even though that makes no sense:
[[VMSocialShareManager defaultManager] shareItems:shareItems fromViewController:self anchorView:shareCell completion:^(BOOL completed, NSString *activityType, NSError *error) {
...
}];
But then that gives the error:
Incompatible block pointer types sending 'void (^)(BOOL, NSString *__strong, NSError *__strong)' to parameter of type 'void (^)(NSString *__strong, BOOL, NSError *__strong)'
So, turns out I just needed to put activityType in the middle, in between success and error. No idea why, but it compiles now:
- (void)shareItems:(NSArray *)shareItems fromViewController:(UIViewController *)viewController anchorView:(UIView *)anchorView completion:(void (^)(BOOL success, NSString *activityType, NSError *error))completionHandler;
You don't have names for the other two items in your block in your declaration. It should be:
- (void)shareItems:(NSArray *)shareItems
fromViewController:(UIViewController *)viewController
anchorView:(UIView *)anchorView
completion:(void (^)(NSString *name, BOOL flag, NSError *error))completionHandler;
You are missing the flag and error parameter names.
Edit: to show that the order of the parameters really doesn't matter, I have created a test project with the above method signature in the AppDelegate, and called it in the application:didFinishLaunchingWithOptions:. It runs as expected. I've attached the sample project here.
I am a little bit confused about objective c programming with blocks.
for example Here is a method:
in the .h
- (void)downloadDataWithURLString:(NSString *)urlString
completionHandler:(void(^) (NSArray * response, NSError *error))completionHandler;
in the .m:
- (void)downloadedDataURLString:(NSString *)urlString
completionHandler:(void (^)(NSArray *, NSError *))completionHandler {
// some things get done here. But what!?
}
My main questions is.... how do I implement this completion handler? What variables would be returned with the array and error? it is one area for the code but how do I tell it what to do when it is completed?
It's up to the caller to supply code to be run by the method (the body of the block). It's up to the implementor to invoke that code.
To start with a simple example, say the caller just wanted you to form an array with the urlString and call back, then you would do this:
- (void)downloadedDataURLString:(NSString *)urlString
completionHandler:(void (^)(NSArray *, NSError *))completionHandler {
NSArray *callBackWithThis = #[urlString, #"Look ma, no hands"];
completionHandler(callBackWithThis, nil);
}
The caller would do this:
- (void)someMethodInTheSameClass {
// make an array
[self downloadedDataURLString:#"put me in an array"
completionHandler:^(NSArray *array, NSError *error) {
NSLog(#"called back with %#", array);
}];
}
The caller will log a two item array with #"put me in an array" and #"Look ma, no hands". In a more realistic example, say somebody asked you to call them back when you're finished downloading something:
- (void)downloadedDataURLString:(NSString *)urlString
completionHandler:(void (^)(NSArray *, NSError *))completionHandler {
// imagine your caller wants you to do a GET from a web api
// stripped down, that would look like this
// build a request
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// run it asynch
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
// imagine that the api answers a JSON array. parse it
NSError *parseError;
id parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
// here's the part you care about: the completionHandler can be called like a function. the code the caller supplies will be run
if (!parseError) {
completionHandler(parse, nil);
} else {
NSLog(#"json parse error, error is %#", parseError);
completionHandler(nil, parseError);
}
} else {
NSLog(#"error making request %#", error);
completionHandler(nil, error);
}
}];
// remember, this launches the request and returns right away
// you are calling the block later, after the request has finished
}
While I can't be entirely sure without seeing any more details about the method, or its exact implementation I suspect this: this methods creates a new background thread, retrieves the data from the server and converts the JSON/XML to an NSArray response. If an error occurred, the error object contains a pointer to the NSError. After doing that, the completion handler is called on the main thread. The completion handler is the block in which you can specify which code should be executed after attempting to retrieve the data.
Here is some sample code on how to call this method to get you started:
[self downloadDataWithURLString:#"http://www.google.com"
completionHandler:^(NSArray *response, NSError *error) {
if (! error) {
// Do something awesome with the 'response' array
} else {
NSLog(#"An error occured while downloading data: %#", error);
}
}];
there are a lot of questions like this and i'm experienced with json format too but i couldnt parse the response below(at the bottom):
I'm using NSJSONSerialization for parsing the response into NSDictionary but the it gives the error like below:
My code:
NSString *subURL= sharedDa.ip;
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://192.168.69.230/tsadmin.php?tssearch=%#", subURL]]];
NSError *error=nil;
NSDictionary* portsResult=[NSJSONSerialization JSONObjectWithData:data options:
NSJSONReadingMutableContainers error:&error];
NSDictionary * tempPorts;
NSString *k;
for(k in [portsResult allKeys]){
tempPorts = [portsResult objectForKey:k];
NSLog(#"Temporary ports: %#", tempPorts);
}
And the error code is below:
2012-09-28 18:47:37.508 BNTPRO ST Manager[2609:fb03] -[__NSArrayM allKeys]: unrecognized selector sent to instance 0x6b83ed0
2012-09-28 18:47:37.511 BNTPRO ST Manager[2609:fb03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM allKeys]: unrecognized selector sent to instance 0x6b83ed0'
*** First throw call stack:
(0x1568022 0x1b20cd6 0x1569cbd 0x14ceed0 0x14cecb2 0x57cd 0x28fa1e 0x28fd11 0x2a18fd 0x2a1aef 0x2a1dbb 0x2a285f 0x2a2e06 0x2a2a24 0x3e59 0x2595c5 0x2597fa 0xaee85d 0x153c936 0x153c3d7 0x149f790 0x149ed84 0x149ec9b 0x245a7d8 0x245a88a 0x1c8626 0x26d2 0x2645 0x1)
terminate called throwing an exception(lldb)
now my data snippet is: [{"k1":{"v":"0"}},{"k2":{"v":"0"}},{"k3":{"v":"0"}},{"k4":{"v":"0"}},{"k5":{"v":"0"}},{"k6":{"v":"0"}},{"k7":{"v":"1"}},{"k8":{"v":"0"}},{"k9":{"v":"1"}},{"k10":{"v":"0"}},{"k11":{"v":"1"}},{"k12":{"v":"0"}},{"k13":{"v":"1"}},{"k14":{"v":"0"}},{"k15":{"v":"0"}},{"k16":{"v":"0"}}]
but it still gives the same error.. even i decşare the iVar as NSDictionary why does it complain of nsmutable array??
The JSON you're parsing is an array, not an object. So the result of [NSJSONSerialization JSONObjectWithData...] is not an NSDictionary *, but an NSArray * instead.
For example, for the JSON data
[{"k1":{"v":"0"}}, {"k2":{"v":"0"}}]
You can use something similar to this code (don't have xcode right now to try to run it):
NSArray * arr = [NSJSONSerialization JSONObjectWithData:data options:...];
int i;
for (i = 0; i < [arr count]; i++) {
NSDictionary * dic = [arr objectAtIndex:i];
NSString * k;
for (k in [dic allKeys]) {
NSLog(#"Temporary ports: %#", [dic objectForKey:k]);
}
}
I am very new to ios development, I am trying to add some values from NSMutableDictionary to NSMutableArray, when I run the code I get this error
2012-05-29 14:09:34.913 iShop[7464:f803] -[__NSCFArray objectForKey:]:
unrecognized selector sent to instance 0x6e423d0 2012-05-29
14:09:34.915 iShop[7464:f803] * Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[__NSCFArray
objectForKey:]: unrecognized selector sent to instance 0x6e423d0'
* First throw call stack: (0x13cb022 0x155ccd6 0x13cccbd 0x1331ed0 0x1331cb2 0x2bb7 0x13cce42 0x93b9df 0x139f94f 0x1302b43 0x1302424
0x1301d84 0x1301c9b 0x12b47d8 0x12b488a 0x15626 0x28bd 0x2825)
terminate called throwing an exception(lldb)
below is my code:
-(void) getData:(NSData *) response {
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:&error];
//NSLog(#"%#", json);
jsonArray = [[NSMutableArray alloc] init];
jsonArray = [json objectForKey:#"Name"];
NSLog(#"%#", jsonArray);
}
- (void)viewDidLoad {
[super viewDidLoad];
jsonURL = [NSURL URLWithString:#"http://localhost:8888/read_product_list.php"];
dispatch_async(BgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:jsonURL];
[self performSelectorOnMainThread:#selector(getData:)
withObject:data waitUntilDone:YES];
});
}
JSONObjectWithData return an object of type id. depending on the structure of your received json data.
The data recieved is eiher NSDictionary or NSArray. In your case I am guessing the top level object is of type NSArray which does not respond to objectForKey
Having some trouble accessing the JSON data in the following URL ( http://jamesstenson.com/portraits/?json=1 ), basically I want to access the "full" "url"'s underneath "attachments". My code at the moment is as follows:
NSError *e = nil;
NSData *jsonFeed = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://jamesstenson.com/portraits/?json=1"]];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:jsonFeed options:NSJSONReadingMutableContainers error: &e];
if (!jsonData) {
NSLog(#"Error parsing JSON: %#", e);
} else {
for(NSDictionary *item in [jsonData objectForKey:#"page"]) {
for(NSDictionary *attachment in [item objectForKey:#"images"]) {
NSLog(#"%#", attachment);
}
}
}
This keeps throwing up an error:
2011-12-21 10:13:39.362 JSON[3463:f803] -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x6a7b500
2011-12-21 10:13:39.363 JSON[3463:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x6a7b500'
I am aware I am accessing the items wrongly, but cannot figure out how to achieve this. I've tried several solutions such as http://blogs.captechconsulting.com/blog/nathan-jones/getting-started-json-ios5 - but no luck. I am complete newbie to iOS development and have a little knowledge of JSON. Thanks for everyones help in advance.
The problem is in you for loop
for(NSDictionary *item in [jsonData objectForKey:#"page"])
You won't get NSDictionary in item, it will return you key of Dictionary, which would be NSString
Check this link for each loop in objective c for accessing NSMutable dictionary to know how to traverse through NSDictionay
Below is the modified code for your requirement, might help you
if (!jsonData) {
NSLog(#"Error parsing JSON: %#", e); } else {
NSArray *attachments = [[jsonData objectForKey:#"page"] objectForKey:#"attachments"];
for(NSDictionary *object in attachments) {
NSLog(#"%#", [object objectForKey:#"images"]);
NSLog(#"%#", [[[object objectForKey:#"images"] objectForKey:#"full"] objectForKey:#"url"]);
}
}