Sudzc (www.sudcz.com) appears that it is no longer a project that is being contributed to!
After a year of no commits and some serious bugs especially with returning list of objects this helpful tool appears to be fading into the black holes of the internet.
I was wondering if anyone knew of an alternative tool that works the same way as this?
Or are soap requests no longer a preferred method of data transfer? Is json a better approach using rest clients?
Bonus question: Is there a way to make sudzc handle a returned list of objects
Some alternatives are:
Easy WSDL
Wsdl2Code
This answer mentions another alternative, wsdl2objc.
Within the generated SoapRequest.m file there you can find the implementation of
- (void) connectionDidFinishLoading:(NSURLConnection *) connection
Look for
if([deserializeTo respondsToSelector: #selector(initWithNode:)])
{
element = [element childAtIndex:0];
output = [deserializeTo initWithNode: element];
}
and remove the line with "element = [...]". If you do so keep in mind that you could have to do fixes in other parts of your generated .m files because of this change. This depends heavily on your WebService layout. Hope this helps.
Related
I have ASP.NET webservice(Asmx) which I need to consume in Cocoa/Objective-C. What is the simplest/optimal way to achieve this? I have done the implementation where we have many delegates for XMLParser and connection. like didStartElement, didEndElement....
Is there any other way to achieve this? In .NET I have done a similar implementation where I have a proxy class and when I make a call to the web method I get a response which is the return value of the web method rather than parsing the response xml.
Please let me know.
Try out some of the existing network frameworks before writing your own (RESTKit, AFNetworking, etc.) - They all have good tutorials on how to easily consume webservices.
A little bit off-topic, but it seems that your Webservice returns a XML response. I would (but that's just me!) try to change that to JSON. Cocoa/Obj-C provides built-in functions to deserialize JSONs, and the aforementioned frameworks also work quite well with this format. It's far easier to use than NSXMLParser etc.
I've been working on a rewrite of my model layer to use across several existing apps. The existing codebase is dated and I'd like to generalize my approach to lend to easier extension in the future and get the benefits of more recent language / technology additions (ARC for one).
My goal is a portable, SQL-backed "framework" consisting of a simple database layer (built on top of FMDatabase) and robust model object class which together encapsulate most of the complexity. Model objects subclass from the main superclass and abide by a contract to implement (and override) methods that provide necessary property and schema details to facilitate SQL actions.
I've used this approach with much success in PHP but have run into issues with Objective-C.
Yes, CoreData provides these things but is not an option for a number of reasons. I've also seen solutions that solve the problem at runtime but I'm not sure that would work with ARC, and would prefer to generate the accessors prior to compilation.
I started with the debate of maintaining a lock based pattern for multi-threaded access vs a GCD based approach (question raised here) and have ended up with the following pattern:
- (NSDate *)creationDate {
__block NSDate *aDate;
dispatch_sync(accessorQueue, ^{
aDate = creationDate;
});
return aDate;
}
- (void)setCreationDate:(NSDate *)aDate {
if (![aDate isKindOfClass: [NSDate class]]) {
NSLog(#"setCreationDate: called with non-date object);
return;
}
dispatch_barrier_async(accessorQueue, ^{
if ((!creationDate && aDate) || ![aDate isEqualToDate: creationDate]) {
[self willChangeValueForKey: #"creationDate"];
[changes setObject: aDate ? aDate : [NSNull null]
forKey: #"creationDate"];
creationDate = aDate;
[self didChangeValueForKey: #"creationDate"];
}
});
}
I like it but I want to be able to generate for a list of properties to simplify the model object code. My first step would be to create macro expansion to build the accessors/mutators. Here I've already run into less-than-perfect options though.
1) Iterating on lists in macros is an ugly process. Boost.preprocessor may be an option but considering (2 & 3) it kind of scares me.
2) Macros need to be passed in all possible versions of the tokens used (ie. I'd have to pass in creationDate and CreationDate just to satisfy generating the getter and setter for the example above.) Not a show-stopper but not ideal either.
3) A different macro expansion is needed for object and primitive types which makes iterating over a list of properties (1) even more difficult. I could pass in the expansion macro for each property in the list but this "time saver" is now looking like quite the opposite – a long list of tuples is not much more readable than a list of individual calls to macros.
I'm hoping I've overlooked something that makes this possible or perhaps someone has already built a drop in solution that I haven't found. Maybe a preprocessing script to generate categories containing the accessors...? I haven't looked into that option yet but would be ok with it, especially if it extended to other languages for cross-platform targeting.
Advice appreciated.
I ended up writing a Python script that looks at the property declarations in my model object header files and writes out custom accessors in a new category for each class. To facilitate this, I annotate my property declarations with a comment string of the form:
// SqlFieldName SqlFieldType
And I've defined several basic templates for object vs primitive accessors.
The results are very implementation specific but saves a lot of copy/paste/find/replace work for accessors which is usually a source of at least 1 bug due to oversight in renaming during find/replace.
Using a category to store the accessors leads to compilation warnings for overriding object methods in a category but you can silence those with -Wobjc-protocol-method-implementation.
My generated code is quite specific to my needs but if anyone is interested I'll post it.
ObjC has a very unique way of overriding methods. Specifically, that you can override functions in OSX's own framework. Via "categories" or "Swizzling". You can even override "buried" functions only used internally.
Can someone provide me with an example where there was a good reason to do this? Something you would use in released commercial software and not just some hacked up tool for internal use?
For example, maybe you wanted to improve on some built in method, or maybe there was a bug in a framework method you wanted to fix.
Also, can you explain why this can best be done with features in ObjC, and not in C++ / Java and the like. I mean, I've heard of the ability to load a C library, but allow certain functions to be replaced, with functions of the same name that were previously loaded. How is ObjC better at modifying library behaviour than that?
If you're extending the question from mere swizzling to actual library modification then I can think of useful examples.
As of iOS 5, NSURLConnection provides sendAsynchronousRequest:queue:completionHandler:, which is a block (/closure) driven way to perform an asynchronous load from any resource identifiable with a URL (local or remote). It's a very useful way to be able to proceed as it makes your code cleaner and smaller than the classical delegate alternative and is much more likely to keep the related parts of your code close to one another.
That method isn't supplied in iOS 4. So what I've done in my project is that, when the application is launched (via a suitable + (void)load), I check whether the method is defined. If not I patch an implementation of it onto the class. Henceforth every other part of the program can be written to the iOS 5 specification without performing any sort of version or availability check exactly as if I was targeting iOS 5 only, except that it'll also run on iOS 4.
In Java or C++ I guess the same sort of thing would be achieved by creating your own class to issue URL connections that performs a runtime check each time it is called. That's a worse solution because it's more difficult to step back from. This way around if I decide one day to support iOS 5 only I simply delete the source file that adds my implementation of sendAsynchronousRequest:.... Nothing else changes.
As for method swizzling, the only times I see it suggested are where somebody wants to change the functionality of an existing class and doesn't have access to the code in which the class is created. So you're usually talking about trying to modify logically opaque code from the outside by making assumptions about its implementation. I wouldn't really support that as an idea on any language. I guess it gets recommended more in Objective-C because Apple are more prone to making things opaque (see, e.g. every app that wanted to show a customised camera view prior to iOS 3.1, every app that wanted to perform custom processing on camera input prior to iOS 4.0, etc), rather than because it's a good idea in Objective-C. It isn't.
EDIT: so, in further exposition — I can't post full code because I wrote it as part of my job, but I have a class named NSURLConnectionAsyncForiOS4 with an implementation of sendAsynchronousRequest:queue:completionHandler:. That implementation is actually quite trivial, just dispatching an operation to the nominated queue that does a synchronous load via the old sendSynchronousRequest:... interface and then posts the results from that on to the handler.
That class has a + (void)load, which is the class method you add to a class that will be issued immediately after that class has been loaded into memory, effectively as a global constructor for the metaclass and with all the usual caveats.
In my +load I use the Objective-C runtime directly via its C interface to check whether sendAsynchronousRequest:... is defined on NSURLConnection. If it isn't then I add my implementation to NSURLConnection, so from henceforth it is defined. This explicitly isn't swizzling — I'm not adjusting the existing implementation of anything, I'm just adding a user-supplied implementation of something if Apple's isn't available. Relevant runtime calls are objc_getClass, class_getClassMethod and class_addMethod.
In the rest of the code, whenever I want to perform an asynchronous URL connection I just write e.g.
[NSURLConnection sendAsynchronousRequest:request
queue:[self anyBackgroundOperationQueue]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *blockError)
{
if(blockError)
{
// oh dear; was it fatal?
}
if(data)
{
// hooray! You know, unless this was an HTTP request, in
// which case I should check the response code, etc.
}
/* etc */
}
So the rest of my code is just written to the iOS 5 API and neither knows nor cares that I have a shim somewhere else to provide that one microscopic part of the iOS 5 changes on iOS 4. And, as I say, when I stop supporting iOS 4 I'll just delete the shim from the project and all the rest of my code will continue not to know or to care.
I had similar code to supply an alternative partial implementation of NSJSONSerialization (which dynamically created a new class in the runtime and copied methods to it); the one adjustment you need to make is that references to NSJSONSerialization elsewhere will be resolved once at load time by the linker, which you don't really want. So I added a quick #define of NSJSONSerialization to NSClassFromString(#"NSJSONSerialization") in my precompiled header. Which is less functionally neat but a similar line of action in terms of finding a way to keep iOS 4 support for the time being while just writing the rest of the project to the iOS 5 standards.
There are both good and bad cases. Since you didn't mention anything in particular these examples will be all-over-the-place.
It's perfectly normal (good idea) to override framework methods when subclassing:
When subclassing NSView (from the AppKit.framework), it's expected that you override drawRect:(NSRect). It's the mechanism used for drawing views.
When creating a custom NSMenu, you could override insertItemWithTitle:action:keyEquivalent:atIndex: and any other methods...
The main thing when subclassing is whether or not your behaviour completes re-defines the old behaviour... or extends it (in which case your override eventually calls [super ...];)
That said, however, you should always stand clear of using (and overriding) any private API methods (those normally have an underscore prefix in their name). This is a bad idea.
You also should not override existing methods via categories. That's also bad. It has undefined behaviour.
If you're talking about categories, you don't override methods with them (because there is no way to call original method, like calling super when subclassing), but only completely replace with your own ones, which makes the whole idea mostly pointless. Categories are only useful for safely extending functionality, and that's the only use I have even seen (and which is a very good, an excellent idea), although indeed they can be used for dangerous things.
If you mean overriding by subclassing, that is not unique. But in Obj-C you can override everything, even private undocumented methods, not just what was declared 'overridable' like in other languages. Personally, I think it's nice, as I remember in Delphi and C++ I used to “hack” access to private and protected members to workaround an internal bug in framework. This is not a good idea, but at some moments it can be a life saver.
There is also method swizzling, but that's not standard language feature, that's a hack. Hacking undocumented internals is rarely a good idea.
And regarding “how can you explain why this can best be done with features in ObjC”, the answer is simple — Obj-C is dynamic, and this freedom is common to almost all dynamic languages (Javascript, Python, Ruby, Io, a lot more). Unless artificially disabled, every dynamic language has it.
Refer to the wikipedia page on dynamic languages for longer explanation and more examples. For example, an even more miraculous things possible in Obj-C and other dynamic languages is that an object can change it's type (class) in place, without recreation.
I am beginner to iphone. My requirement is to invoke the sap webservice in iphone.I got the result data which is in xml form.The result is to be in NSString which is of Xml form.Then how to get that result into the array in xcode.Please help me.
Here is a great library on GitHub-XML to NSDictionary
It isn't quite an NSArray but xml files are rarely just Arrays, so this provides an intermediate, dictionaries when needed, arrays if possible.
1. You can use NSXMLParser for this purpose, read through the delegate methods in https://developer.apple.com/library/ios/documentation/cocoa/reference/NSXMLParserDelegate_Protocol/Reference/Reference.html
2. This question is pretty repetitive, you could have just googled "Parsing the Xml data in iPhone" or "Parsing the Xml data using xCode" you would have got loads of results. Go trhough this ->
http://www.xcode-tutorials.com/parsing-xml-files/
and maybe this-> http://www.edumobile.org/iphone/iphone-programming-tutorials/parsing-an-xml-file/
3. Next time please do search.
Your question is quite general and it's difficult to give you a specific answer.
Here some guidelines to consume web services in iOS.
First, you need to have a mechanism that helps you to consume the ws. To do it, you can use NSUrlConnection class (see NSURLConnection Class) or use a the ASIHttpRequest framework (see ASIHTTPRequest). In this manner you can make requests and dowload response messages.
Since you use soap messages, you have first to create the request message manually. You can use class method of NSString stringWithFormat or use ASIFormDataRequest class of ASIHttpRequest framework.
Finally, if you receive a message that is like the following you posted in your comment, you need to parse it. Remember that is a soap message and it doesn't have only your tags. To do it, you can use NSXMLParser class (see NSXMLParser Class) or use GDataXML parser (see how-to-read-and-write-xml-documents-with-gdataxml).
Out there there are plenty of tutorials or posts on how to "consume web services on iOS". You can find them. In addition, there are also some kits that, taken the your service, create class wrappers to consume your services. In this case you don't need to create or parse manually masseges.
A last remark. When you need to consume data taken from a service, maybe a REST architecture could be easier to set up.
Hope it helps.
I have never made an API in objective-c, and need to do this now.
The "idea" is that I build an API which can be implemented into other applications. Much like Flurry, only for other purposes.
When starting the API, an username, password and mode should be entered. The mode should either be LIVE or BETA (I guess this should be an NSString(?)), then afterwards is should be fine with [MyAPI doSomething:withThisObject]; ect.
So to start it [MyAPI username:#"Username" password:#"Password" mode:#"BETA"];
Can anyone help me out with some tutorials and pointer on how to learn this best?
It sounds like what you want to do is build a static library. This is a compiled .a file containing object code that you'll distribute to a client along with a header file containing the interface. This post is a little outdated but has some good starting points. Or, if you don't mind giving away your source code, you could just deliver a collection of source files to your client.
In terms of developing the API itself, it should be very similar to the way you'd design interfaces and implementations of Objective-C objects in your own apps. You'll have a MyAPI class with functions for initialization, destruction, and all the functionality you want. You could also have multiple classes with different functionality if the interface is complex. Because you've capitalized MyAPI in your code snippet, it looks like you want to use it by calling the class rather than an instance of the class - which is a great strategy if you think you'll only ever need one instance. To accomplish this you can use the singleton pattern.
Because you've used a username and password, I imagine your API will interface with the web internally. I've found parsing JSON to be very straightforward in Objective-C - it's easy to send requests and get information from a server.
Personally I would use an enum of unsigned ints rather than a NSString just because it simplifies comparisons and such. So you could do something like:
enum {
MYAPI_MODE_BETA,
MYAPI_MODE_LIVE,
NUM_MYAPI_MODES
};
And then call:
[MyAPI username:#"Username" password:#"Password" mode:MYAPI_MODE_BETA];
Also makes it easy to check if they've supplied a valid mode. (Must be less than NUM_MYAPI_MODES.)
Good luck!