0

I have a requirement of writing a custom data, before the actual write of NSOutputStream happens.

To make swizzling code execute, i have created a category NSOutputStream(SwizzleWrite), which contains the following:

SEL originalSelector = @selector(write:maxLength:);
SEL swizzledSelector = @selector(swizzledWrite:maxLength:);

Method originalMethod = class_getInstanceMethod([NSOutputStream class], originalSelector);
Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);

method_exchangeImplementations(originalMethod, swizzledMethod);

I then create Inout & Output stream: CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, hostRef, 80, &readStream, &writeStream);

inputStream = (__bridge_transfer NSInputStream *)readStream;
outputStream = (__bridge_transfer NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];

But now when the control reaches handleEvent: delegate, specifically on: [outputStream write:rawstring maxLength:sizeof(rawstring)];, i do not get it on swizzledWrite:maxLength:

What am i doing wrong here?

PS: I have read that swizzling Apple methods is not Appstore-friendly, but i have also read cases where they are accepted.

1 Answers1

0

Why do you feel that swizzling is the best option here? Sounds to me like a subclass would be much better. There are some tricky parts about subclassing a stream but take a look here

If you are determined to make swizzling work, have you set breakpoints and made sure that your swizzling selectors are not nil? Might happen if you get the signatures a bit wrong

Yaser
  • 408
  • 2
  • 6
  • Oh maybe I read your question wrong. Is the problem that handleEvent is not called on your swizzled function? – Yaser Nov 29 '14 at 08:08
  • Hey Yaser, i get valid references for both original and to-be-swizzled-with selectors. I am not swizzling handleEvent: It is working the way it should be. Problem is when i get NSStreamEventHasSpaceAvailable i call write:maxLength, ideally i should get a call on the swizzled selector but i dont. – user1125968 Nov 29 '14 at 10:15
  • Also, i don't know if swizzling is the best option here but subclassing won't help as the code i am working on is exposed as a framework. – user1125968 Nov 29 '14 at 10:19
  • Okay, so I understood you correct. Are you sure you are running the swizzling code only once? – Yaser Nov 29 '14 at 16:10
  • I do #import "NSOutputStream+SwizzleWrite.h" in AppDelegate, that calls the 'load' method of this class. I have a breakpoint at the load method. I get the control only once. – user1125968 Nov 30 '14 at 03:42