繁体   English   中英

快速将UnsafeMutableRawPointer转换为String(utf8)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM