简体   繁体   English

快速将UnsafeMutableRawPointer转换为String(utf8)

[英]Converting UnsafeMutableRawPointer to String(utf8) in swift

The question is simple How to convert UnsafeMutableRawPointer? 问题很简单,如何转换UnsafeMutableRawPointer? to String(encoding: utf8) in swift. 快速转换为String(encoding: utf8)

I get some data from socket written in obj c, the model class looks like 我从用obj c编写的套接字中获取了一些数据,模型类看起来像

@interface PTData : NSObject
@property (readonly) dispatch_data_t dispatchData;
@property (readonly) void *data;
@property (readonly) size_t length;
@end

The corresponding obj c code for converting data to String 相应的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];

Here PTExampleTextFrame is a struct 这里PTExampleTextFrame是一个struct

typedef struct _PTExampleTextFrame {
  uint32_t length;
  uint8_t utf8text[0];
} PTExampleTextFrame; 

But I can't convert the code to swift. 但是我无法将代码转换为swift。 But when I tried to convert the code looks like, 但是当我尝试转换代码时,

let data = Data(bytesNoCopy: payload!.data, count: payload.length,deallocator: .none)

let text = String(bytes: data, encoding: String.Encoding.utf8)

Somehow I got the answer but the text is prefixed with some escape characters. 我不知何故得到了答案,但是文本的开头带有一些转义字符。

hi makes \\0\\0\\0\\u{02}jj hi\\0\\0\\0\\u{02}jj

long text to \\0\\0L\\u{1D}long text long text\\0\\0L\\u{1D}long text

I didn't get the concept of UnsafeMutableRawPointer and what is the prefixes. 我没有得到UnsafeMutableRawPointer的概念以及前缀是什么。

If your obj c code for converting data to String is confirmed to work properly, I recommend you to write an Objective-C extension to work with Swift. 如果确认将数据转换为String的obj c代码可以正常工作,则建议您编写一个Objective-C扩展以与Swift一起使用。

Such as: 如:

PTData+Swift.h 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 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 {YourProject} -Bridging-Header.h

#import "PTData.h"
#import "PTData+Swift.h"

(You may need to modify #import "PTData.h" to include actual headers.) (您可能需要修改#import "PTData.h"以包括实际的标头。)

With the above extension, you can simply write in Swift: 使用以上扩展,您可以简单地用Swift编写:

debugPrint(payload.message)

Or else, if you dare insist on writing a Swift equivalent of your obj c code for converting data to String , your Swift code shown is a little bit too short. 否则,如果您敢于坚持编写与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)

I have tested above codes with minimum estimated data, but it may be different than the actual data you receive. 我已经用最少的估计数据测试了上述代码,但它可能与您收到的实际数据有所不同。 Please try and tell me if you find something wrong. 如果您发现问题,请尝试告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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