[英]Converting UnsafeMutableRawPointer to String(utf8) in swift
问题很简单,如何转换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
相应的obj c代码,用于将数据转换为String
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
的概念以及前缀是什么。
如果确认将数据转换为String的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)
否则,如果您敢于坚持编写与obj c代码等效的Swift 来将数据转换为String ,那么显示的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)
我已经用最少的估计数据测试了上述代码,但它可能与您收到的实际数据有所不同。 如果您发现问题,请尝试告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.