问题很简单,如何快速将UnsafeMutableRawPointer?
转换为String(encoding: utf8)
。
我从用obj c编写的套接字中获取了一些数据,模型类看起来像
@interface PTData : NSObject
@property (readonly) dispatch_data_t dispatchData;
@property (readonly) void *data;
@property (readonly) size_t length;
@end
用于将数据转换为String的相应obj c代码
PTExampleTextFrame *textFrame = (PTExampleTextFrame*)payload.data;
textFrame->length = ntohl(textFrame->length);
NSString *message = [[NSString alloc] initWithBytes:textFrame->utf8text length:textFrame->length encoding:NSUTF8StringEncoding];
这里PTExampleTextFrame
是struct
typedef struct _PTExampleTextFrame {
uint32_t length;
uint8_t utf8text[0];
} PTExampleTextFrame;
但是我无法将代码转换为swift。但是当我尝试转换代码时,
let data = Data(bytesNoCopy: payload!.data, count: payload.length,deallocator: .none)
let text = String(bytes: data, encoding: String.Encoding.utf8)
我以某种方式得到了答案,但是文本的开头带有一些转义字符。
hi
使\0\0\0\u{02}jj
long text
至\0\0L\u{1D}long text
我没有得到UnsafeMutableRawPointer
的概念以及前缀是什么。
答案 0 :(得分:2)
如果确认将数据转换为字符串的 obj c代码正常工作,建议您编写一个Objective-C扩展以与Swift一起使用。
例如:
PTData + Swift.h
#import <Foundation/Foundation.h>
@class PTData;
NS_ASSUME_NONNULL_BEGIN
@interface PTData (Swift)
@property (readonly) NSString *message;
@end
NS_ASSUME_NONNULL_END
PTData + Swift.m
#import "PTData.h"
#import "PTData+Swift.h"
@implementation PTData (Swift)
- (NSString *)message {
PTExampleTextFrame *textFrame = (PTExampleTextFrame*)self.data;
uint32_t length = ntohl(textFrame->length);
NSString *message = [[NSString alloc] initWithBytes:textFrame->utf8text
length:length
encoding:NSUTF8StringEncoding];
return message;
}
@end
{YourProject} -Bridging-Header.h
#import "PTData.h"
#import "PTData+Swift.h"
(您可能需要修改#import "PTData.h"
以包括实际的标头。)
有了以上扩展,您可以简单地用Swift编写:
debugPrint(payload.message)
否则,如果您不敢编写与将代码转换为String的 obj c代码等效的Swift ,则显示的Swift代码就太短了。
extension PTData {
var textFrameMessage: String {
let textFrame = self.data.assumingMemoryBound(to: PTExampleTextFrame.self)
let length = Int(textFrame.pointee.length.bigEndian)
let utf8text = self.data
.advanced(by: MemoryLayout<UInt32>.size) // <- Sadly enough, `MemoryLayout.offset(of:)` does not work as expected for `utf8text`
.assumingMemoryBound(to: UInt8.self)
let bytes = UnsafeBufferPointer(start: utf8text, count: length)
let message = String(bytes: bytes, encoding: .utf8)! // <- This may crash, if the message is not encoded in UTF-8
return message
}
}
debugPrint(payload.textFrameMessage)
我已经用最少的估计数据测试了上述代码,但可能与您收到的实际数据有所不同。如果您发现问题,请尝试告诉我。