IOS sudzc arc empty second response, first works without problems - iphone

i'm using the generated acr code from sudzc in my iPhone project. i already imported the missing h files, fixed the body tag and everything works fine...for the first call of any function.
i call the functions in several positions in my code like in the viewDidLoad:
TestWsdlService_ManagerService* service = [TestWsdlService_ManagerService service];
[service getAttended:self action:#selector(getEventsHandler:) email: #"testmail#bla.com" password: #"testpass"];
first call works well. logging is enabled so i see the correct post and the correct response.
when i call the same functions again, i only see the correct post but it gives me that error with an empty response (no xml, nothing):
2012-08-14 10:26:55.574 Test[1768:11603] nserror Error Domain=CXMLErrorDomain Code=1
"Unknown error" UserInfo=0x6e5fea0 {NSLocalizedDescription=Unknown error}
2012-08-14 10:26:55.580 Test[1768:11603] Error: Unknown error
i also tried it with a singleton like this:
static TestSoapSingleton *sharedInstance = nil;
+ (TestSoapSingleton *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
- (id)init
{
self = [super init];
if (self) {
self.manager = [TestWsdlApi_ManagerService service];
self.manager.logging = YES;
self.username =#"testmail#blub.com";
self.password = #"test pass";
}
but at the end i got the same error.
the error is thrown in the CXMLDocument.m in the initWithData function, because the inData is empty (size=0).
also in the SoapRequest.m in the connectionDidFinishLoading function, the receivedData is empty.
i tried to debug the SoapRequest.m and detected, that the didReceiveResponse is called in the first and the second call of a function, but the didReceiveData is only called at the first time.
if i do two method calls right behind each other like this:
TestWsdlService_ManagerService* service = [TestWsdlService_ManagerService service];
[service getAttended:self action:#selector(getEventsHandler:) email: #"testmail#bla.com" password: #"testpass"];
TestWsdlService_ManagerService* service2 = [TestWsdlService_ManagerService service];
[service2 getAttended:self action:#selector(getEventsHandler:) email: #"testmail#bla.com" password: #"testpass"];
it also works without problems.
hope anybody has a solution, thanks

after several hours i found the bug...webserver problem / session problem. got issues with the zend::auth adapter
but i wonder why the ksoap2 api is working with the session things and the nsurlconnection not^^

Related

How to access the method in the Private API framework and pass the value to it?

First - I know private frameworks/APIs won't get me to the AppStore, this is for private use/research only.
So as for the research purpose I chose MFMessageComposer I want to disable the editing of any inputs both of which are being passed from the code.
I tried to put my hands on this and I coded in the following manner . What I did is I took the path of the private framework and accessed a particular class called as CKSMSComposeController which have the above mentioned methods . I referred the class dump classes of the ChatKit.framework https://github.com/nst/iOS-Runtime-Headers/blob/master/PrivateFrameworks/ChatKit.framework/CKSMSComposeController.h
I am getting the logs of NSLog(#"Result %#", success ? #"YES" : #"NO"); as YES but still I am unable to disable the edit of recepients even after passing NO to the selector above
Can someone tell am I passing the parameter in a correct way ? Because -(void)setCanEditRecipients:(BOOL)arg1;` which is a method in the private framework accepts bool as parameter and I am passing NO in above code
This is just for internal research on private frameworks. Where I am doing wrong ?.Please tell
Class methods start with + and instance methods start with - in Objective-C.
// Following is an instance method because it starts with `-`
- (void)setCanEditRecipients:(bool)arg1;
Above method will NOT work with following code.
Class CKSMSComposeController = NSClassFromString(#"CKSMSComposeController");
SEL sel = NSSelectorFromString(#"setCanEditRecipients:");
// `CKSMSComposeController` is a class - NOT an instance
if ([CKSMSComposeController respondsToSelector:sel]) {
// will not enter if's body
}
On top of all this - you shouldn't create an instance of your own and do customizations on that. You should do the customizations on the instance that's presented by the system on screen.
Here's how you can try that -
- (void) showMessageComposeViewController {
if ([MFMessageComposeViewController canSendText]) {
MFMessageComposeViewController* messageController = [[MFMessageComposeViewController alloc] init];
messageController.recipients = #[#"555-555-5555"];
messageController.body = #"Example message";
[self presentViewController:messageController animated:YES completion:^{
// Allow enough time for the UI to be loaded fully
dispatch_after(1, dispatch_get_main_queue(), ^{
// Since `MFMessageComposeViewController` is a `UINavigationController`, we can access it's first view controller like this
UIViewController* targetVC = messageController.viewControllers.firstObject;
// Check if the instance is of correct class type
if ([targetVC isKindOfClass:NSClassFromString(#"CKSMSComposeController")]) {
SEL sel1 = NSSelectorFromString(#"setCanEditRecipients:");
if ([targetVC respondsToSelector:sel1]) {
// put breakpoint here to check whether this line is executed
[targetVC performSelector:sel1 withObject:#NO];
}
SEL sel2 = NSSelectorFromString(#"setTextEntryContentsVisible:");
if ([targetVC respondsToSelector:sel2]) {
// put breakpoint here to check whether this line is executed
[targetVC performSelector:sel2 withObject:#NO];
}
}
});
}];
}
}

RestKit Handling overlapping RKRequest Delegates

I have several RestKit gets that all use the same format:
[[RKClient sharedClient] get:endString queryParameters:params delegate:self];
I have a masterMethod that essentially refreshes all my user's restful data that looks like this
-(void)masterMethod
{
[self get1];
[self get2];
[self get3];
[self get4];
[self get5];
}
Where all the gets are in the same format as the one above. All of this code is in a class that includes the delegate method:
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
However, I think something is going wrong when I try to call all give gets in the same method. It's as though the delegate didLoadResponse & didRecieveResponse methods are overlapping or getting release or something. Is there a way to make a master queue to handle this huge call? Or is something else going wrong.
I'm getting a BAD_ACCESS error somewhere in the masterMethod call.
Thanks, any help greatly appreciated.
What are you getting? If you're pulling down objects you should us the isKindOfClass method to distinguish the objects in objectLoader:didLoadObjects and set appropriately.
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
if ([[objects objectAtIndex:0] isKindOfClass:[Apple class]]) {
Apple *apple = [objects objectAtIndex:0];
}
else if ([[objects objectAtIndex:0] isKindOfClass:[Banana class]]) {
Banana *banana = [objects objectAtIndex:0];
}
}
If you're pulling data from the request response, look into setting userdata on the request object, then checking the userdata in request:didLoadResponse. For more information see RestKit: distinguish multiple requests in didLoadResponse:.

ObjC object changes to random objects: a memory issue

long time listener, first time caller.
I have a basic memory issue I don't understand, that I'm sure just about any one of you will see in a second. I'm playing around, trying to learn various ways of using UIWebViews, getting strings from URLs, and so on. Specifically, I'm trying to obtain one URL from another. In other words, I have uploaded an html page to the web, containing a URL. The address for that page is coded into the app, giving me a "hook" into the app - I can change the contents of that page and send the app a new URL any time I want. Make sense?
So...retrieving the URL? No problem. Passing it into a string for later use - no problem. But when I set up a tap gesture recognizer, which should take that string, convert it back to an NSURL, and open it in Safari, I get a runtime crash. An NSLog call tells me that the string in question keeps being assigned to all sorts of random things.
The relevant bits of my code follow. I'm sure some of you will tell me there are much better ways to do what I want - and that's certainly welcome. But I'd also really love to know what I'm doing wrong for this particular implementation, as I'm sure it's a basic misunderstanding that I'd like to correct.
Thanks in advance. (And sorry about the formatting of the code block - haven't quite got the hang of posting on here!)
#import "Messing_With_Web_ViewsViewController.h"
#implementation Messing_With_Web_ViewsViewController
#synthesize tapView;
NSString *finalURL;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *firstString = #"http://www.my_web_address.html";
//Of course, I have the correct address here.
NSURL *firstUrl = [NSURL URLWithString:firstString];
NSError * error;
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:&error];
if ( finalURL )
{
NSLog(#"Text=%#", finalURL);
//everything fine up to here; console prints the correct
contents of "my web address"
}
else
{
NSLog(#"Error = %#", error);
}
//Taps
UITapGestureRecognizer *tapRecognizer;
tapRecognizer=[[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(foundTap:)];
tapRecognizer.numberOfTapsRequired=1;
tapRecognizer.numberOfTouchesRequired=1;
[tapView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
}
- (void)foundTap:(UITapGestureRecognizer *)recognizer {
NSLog(#"Trying to load %#", finalURL);
//at this point the app either crashes, or the console shows a random memory object
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: finalURL]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[finalURL release];
[super dealloc];
}
#end
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:&error];
The line above creates an instance of NSString which you do not own (because you did not call a method whose name includes 'new', 'alloc' 'retain', or 'copy' on it). That finalURL with therefore eventually be destroyed when it is no longer needed. By the time your -foundTap: method runs finalURL has been deallocated and you are just referencing the memory location where it used to be and which now may contain some other object or random data.
Read the memory management guidelines again and also learn to run the static analyzer which should point out mistakes like this.

Testing NSWidowController using OCMock

I've been trying to come up with a a way to unit test my applicationDidFinishLaunching delegate using OCMock. My NSWindowController is instantiated here and I'd like to test it. Here's my test code:
id mockWindowController = [OCMockObject niceMockForClass:[URLTimerWindowController class]];
[[mockWindowController expect] showWindow:self];
NSUInteger preRetainCount = [mockWindowController retainCount];
[appDelegate applicationDidFinishLaunching:nil];
[mockWindowController verify];
When I run the test, I get the error:
"OCMockObject[URLTimerWindowController]: expected method was not invoked: showWindow:-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]"
The log gives more detail:
"Test Case '-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]' started.
2011-04-11 08:36:57.558 otest-x86_64[3868:903] -[URLTimerWindowController loadWindow]: failed to load window nib file 'TimerWindow'.
Unknown.m:0: error: -[URLTimerAppDelegateTests testApplicationDidFinishLaunching] : OCMockObject[URLTimerWindowController]: expected method was not invoked: showWindow:-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]
Test Case '-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]' failed (0.005 seconds).
"
So I see that the NIB fails to load. Ok, so how do I make it load while unit testing or somehow mock its load? I've already looked at the OCMock docs, Chris Hanson's tips on unit testing and a few other resources, including the WhereIsMyMac source code which behave in a similar fashion. My application for instantiating the window controller is this:
self.urlTimerWindowController = [[URLTimerWindowController alloc] init];
[self.urlTimerWindowController showWindow:self];
Any tips greatly appreciated.
The problem with your test is that mockWindowController and urlTimerWindowController are not the same object. And self in your test is not the same as self in the class under test. It doesn't really matter that the nib doesn't load in this case.
You generally can't mock an object when it's instantiated inside the method you want to test. One alternative is to instantiate the object in one method, then pass it to another method that finishes the setup. Then you can test the setup method. For example:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.urlTimerWindowController = [[URLTimerWindowController alloc] init];
[self setUpTimerWindow:urlTimerWindowController];
}
-(void)setUpTimerWindow:(URLTimerWindowController *)controller {
[controller showWindow:self];
}
Then, you would test setUpTimerWindow::
-(void)testSetUpTimerWindowShouldShowWindow {
URLTimerAppDelegate *appDelegate = [[URLTimerAppDelegate alloc] init];
id mockWindowController = [OCMockObject niceMockForClass:[URLTimerWindowController class]];
[[mockWindowController expect] showWindow:appDelegate]; // this seems weird. does showWindow really take the app delegate as a parameter?
[appDelegate setUpTimerWindow:mockWindowController];
[mockWindowController verify];
[appDelegate release];
}

How to debug memory allocation issues?

I am writing an iPhone app that that is trying to create a second a view when the user clicks on an element in UITableView. The code looks like
ReplyToViewController *reply = [[ReplyToViewController alloc] initWithNibName:#"ReplyTo" bundle:nil];
reply.delegate = self;
Message *message = [resultData objectAtIndex:indexPath.row];
int dbid = [message.bizid intValue];
NSLog(#"dbid=%d",dbid);
reply.currentMessage = message;
reply.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:reply animated:YES];
The reply object gets created properly and the view is proper. Last line in above code segment calls some framework code which eventually calls the viewDidLoad method of the ReplyToViewController. Address of the reply object in the above code and the address of the object in viewDidLoad is not same.
Any idea where this new object is coming from? How do I debug? I also added init method the following method in ReplyToViewController hoping that it will get called and I can find who is creating this new object. But it does not stop in this method.
Any help will be greatly appreciated.
- (id) init
{
/* first initialize the base class */
self = [super init];
return self;
}
// Following gets called from the 1st code segment.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(currentMessage.text]; // THIS returns nil and the program fails later in the code.
}
I'm sure this is unrelated, but I figure this:
NSLog(currentMessage.text];
Should be this:
NSLog(currentMessage.text);
Also, I've found that Analyzing (Cmd+Shift+A) my code always helps to track down potential memory leaks and prevent overzealous memory allocation.
The most likely explanation is a reporting error.
Usually when people see a different address for an object it's because they used the wrong format descriptor in their log statements.
A common error is:
NSLog(#"Object address=%i", myObject); // any numerical formatter %d,%f...
... which produces a random number. You really want:
NSLog(#"Object address=%%qX",&myObject);
... which dumps the address in hex.
Another mistake is:
NSLog(#"Object address=%%qX",&[myObject description]);
... which returns the address of the description string which changes every time.
There are others but you get the idea.
If you're using log statements, check the address in the debugger instead to confirm it's a different object.
Unrelated, but I would get rid of the class' initializer methods because they don't do anything but call the super. You might as well just let the compiler default to the super if you don't customize.