Mac Chat App,没有获得NSInputStream& NSOutputStream

时间:2015-05-07 10:36:10

标签: python ios objective-c iphone macos

我正在使用一个简单的python localhost服务器的聊天应用程序,使用NSStream通过网络套接字连接发送和接收数据。应用程序在iPhone应用程序中运行良好,但没有在mac应用程序中获得流。

我的Python服务器代码

from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor

class MacChat(Protocol):
  def connectionMade(self):
    print "a client connected"
    self.factory.clients.append(self)
    print "clients are ", self.factory.clients
  def connectionLost(self, reason):
    self.factory.clients.remove(self)
  def dataReceived(self, data):
    a = data.split(':')
    print a
    if len(a) > 1:
        command = a[0]
        content = a[1]

        msg = ""
        if command == "iam":
            self.name = content
            msg = self.name + " has joined"

        elif command == "msg":
            msg = self.name + ": " + content
            print msg

        for c in self.factory.clients:
            c.message(msg)
  def message(self, message):
    self.transport.write(message + '\n')

factory = Factory()
factory.clients = []
factory.protocol = MacChat
reactor.listenTCP(80, factory)
print "Mac Chat server started"
reactor.run()

Mac

ChatViewController.h

#import <Cocoa/Cocoa.h>
@interface ChatViewController : NSViewController
@property (strong,nonatomic) NSString *userName;
@end

ChatViewController.m

#import "ChatViewController.h"


@interface ChatViewController ()<NSTableViewDataSource,NSTableViewDelegate,NSStreamDelegate>
{
  NSInputStream *inputStream;
  NSOutputStream *outputStream;
  NSMutableArray * messages;
}
@property (weak) IBOutlet NSButton *btnSend;
@property (weak) IBOutlet NSTextField *txtMessage;
@property (weak) IBOutlet NSTableView *tableview;
@end

@implementation ChatViewController

- (void)viewDidLoad {
  [super viewDidLoad];

// Do view setup here.
}
-(void)setUserName:(NSString *)userName
{
  [self initNetworkCommunication];
  NSString *response  = [NSString stringWithFormat:@"iam:%@",userName];
  NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
  [outputStream write:[data bytes] maxLength:[data length]];
  messages = [[NSMutableArray alloc] init];
}

- (void)initNetworkCommunication {
  CFReadStreamRef readStream;
  CFWriteStreamRef writeStream;
  CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"localhost", 80, &readStream, &writeStream);
  inputStream = (__bridge_transfer NSInputStream *)readStream;
  outputStream = (__bridge NSOutputStream *)writeStream;
  inputStream.delegate=self;
  outputStream.delegate=self;
  [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  [inputStream open];
  [outputStream open];
}
- (IBAction)btnAtnSend:(id)sender {
  NSString *response  = [NSString stringWithFormat:@"msg:%@",   self.txtMessage.stringValue];
  NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
  [outputStream write:[data bytes] maxLength:[data length]];
  self.txtMessage.stringValue = @"";
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

// Get a new ViewCell
  NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

// Since this is a single-column table view, this would not be necessary.
// But it's a good practice to do it in order by remember it when a table is multicolumn.
  if( [tableColumn.identifier isEqualToString:@"cell"] )
  {
    NSString *s = (NSString *) [messages objectAtIndex:row];
    cellView.textField.stringValue = s;
  }
  return cellView;
}


- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
  return [messages count];
}
-(CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
  return 30;
}
#pragma mark NSStream Delegate

-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
  switch (eventCode) {

    case NSStreamEventOpenCompleted:
        NSLog(@"Stream opened");
        break;

    case NSStreamEventHasBytesAvailable:
        if (aStream == inputStream) {

            uint8_t buffer[1024];
            int len;

            while ([inputStream hasBytesAvailable]) {
                len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
                if (len > 0) {

                    NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

                    if (nil != output) {
                        NSLog(@"server said: %@", output);
                        [self messageReceived:output];

                    }
                }
            }
        }
        break;

    case NSStreamEventErrorOccurred:
        NSLog(@"Can not connect to the host!");
        break;

    case NSStreamEventEndEncountered:
    {
        [aStream close];
        [aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
        break;

    default:
        NSLog(@"Unknown event");
  }
}
- (void) messageReceived:(NSString *)message {
  [messages addObject:message];
  [self.tableview reloadData];
  [self.tableview scrollRowToVisible:messages.count-1];
}
@end

1 个答案:

答案 0 :(得分:0)

行。看起来这是基于raywenderlich.com的示例。

这个例子是有缺陷的,如#34;字形&#34;在评论部分:

  

本教程对数据如何从网络传送到应用程序做出了一些不正确的假设。

在构建此代码之前阅读字形的帖子。

对于您的特定问题,您对原始代码进行了大量更改。乍一看,我不清楚&#34; setUserName&#34;甚至被称为。

没有它,就不会发生任何其他事情。