Hi,
I'm trying to develop a simple client for the RTSP protocol. I'm only interested in exchanging messages such as OPTIONS, DESCRIBE, SETUP, etc. with the server, not actually streaming any media.
Because RTSP is similar to HTTP, I hoped I could use an NSURLSession to talk to the server if I provided a protocol handler for RTSP. So I created a class that extends NSURLProtocol, implemented the +canInitWithRequest method, and registered the class with [NSURLProtocol registerClass:]. Then I put a breakpoint in my canInitWithRequest method and tried to send a dataTask to an rtsp:// URL.
The result is simply an error message "unsupported URL". I'm totally confused by this result, because my canInitWithRequest method was never even called. I expected that it would be, regardless of what ever else happened.
Can someone explain why this is? Also, is it even possible to do what I want to do, without writing a bunch of low-level socket code to talk to the server? I'm willing to write the socket code if I have to, but I was hoping to find a shortcut (and if I have to write the socket code, I don't care whether or not it is integrated with the URL loading system).
Thanks,
Frank
I got past this first issue by using the shared NSURLSession instead of creating a new one.
Right. NSURLSession does support NSURLProtocol but that support varies by session type:
The shared session picks up protocols registered via
.+registerClass:For other standard sessions you have to opt into them by setting the
property on the NSURLSessionConfiguration object you use to create the session.protocolClassesBackground sessions don’t support NSURLProtocol at all.
However, I don’t think that this will help you with this:
is it even possible to do what I want to do, without writing a bunch of low-level socket code to talk to the server?
The HTTP protocol that lurks within NSURLSession will only accept
http and
http URLs. You can’t change that by adding an NSURLProtocol. Specifically:
It seems like I should be able to have my protocol class extend the one that implements the HTTP protocol, but I don't know the name of that class.
Indeed. That class is not public. In fact, it’s not even written in Objective-C (-:
CFNetwork was not designed to facilitate what you’re trying to do. Even if it were, it’s likely that it wouldn’t be possible. While HTTP and RTSP are superficially similar, they’re nowhere near close enough to for this to work. Section 1.8 of RFC 2326 is pretty clear about this.
Using an NSURLProtocol here will have two effects:
You still have to write the code that implements the on-the-wire protocol, but now it’s inside an NSURLProtocol subclass
Clients will be able to access your protocol via the NSURLSession API
The first point is a wash. The second point might be a benefit; ultimately you get to decide whether it’s enough of a benefit to justify the work involved.
Are you implementing RTSP over UDP or TCP? If you’re targeting UDP then, alas, low-level sockets code is the order of the day. If you’re targeting TCP, you should use CFSocketStream (typically via the NSStream API) to get all the benefits it provides (nicer API, TLS support, proxy support).
Also, depending on how close the RTSP protocol is to HTTP, you may be able to use CFHTTPMessage to format and parse messages.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"