简体   繁体   English

为什么不将工作从NSData强制转换为String? 迅速

[英]Why doesn't cast work from NSData to String? Swift

I have that code 我有那个代码

func SendRequest(request: String) -> String
{
    var response = ""
    var (success, errmsg) = client.connect(timeout: 1)
    if success
    {
        var (success, errmsg) = client.send(str: request + "\n" )
        if success
        {
            while(true)
            {
                var data = client.read(10240*10)
                if (data == nil)
                {
                    break
                }
                var bytes = NSData.init(bytes: data!, length: data!.count)
                var str = String.init(data: bytes, encoding: NSUTF8StringEncoding)
                if str != nil{
                response += str!
                }
            }
        }
        else
        {
            print(errmsg)
        }
    }
    else
    {
        print(errmsg)
    }
    return response
}

Sometimes, cast NSData to String doesn't work. 有时,将NSDataString无效。 When I print(str) I see nil . 当我print(str)我看到nil Why is this happening? 为什么会这样呢? I use SwiftSocket library from GitHub. 我使用来自GitHub的SwiftSocket库。 Sorry for my English. 对不起我的英语不好。

This happening when my server send big JSON string. 当我的服务器发送大JSON字符串时,就会发生这种情况。 For example - if i received one object of message (my class) - everything always works. 例如-如果我收到一个消息对象(我的班级)-一切都会正常。 But if i received 4,5,6,... objects of message(my class) - this is working sometimes. 但是,如果我收到4,5,6,...消息对象(我的班级),则有时会起作用。 MAGIC :( 魔法 :(
New version of code 新版本的代码

func SendRequest(request: String) -> String
{
    var response = ""
    var bigData: [UInt8] = []
    var (success, errmsg) = client.connect(timeout: 1)
    if success
    {
        var (success, errmsg) = client.send(str: request + "\n" )
        if success
        {
            while(true)
            {
                var data = client.read(1024*10)
                if (data == nil)
                {
                    break

                }
                bigData.appendContentsOf(data!)
            }
        }
        else
        {
            print(errmsg)
        }
    }
    else
    {
        print(errmsg)
    }
    var bytes = NSData.init(bytes: bigData, length: bigData.count)

    if let str = String(data: bytes, encoding: NSUTF8StringEncoding) as String? {
        print(str)
        response = str
    }
    return response
}

Some possibilities to examine include whether or not data actually contains any bytes, and whether or not it's actually a valid UTF-8 string. 检查的一些可能性包括数据是否实际上包含任何字节,以及它是否实际上是有效的UTF-8字符串。 Assuming this is an http request/response that you're handling, check the Content-type , in particular the charset property. 假设这是您要处理的http请求/响应,请检查Content-type ,尤其是charset属性。 If the data's encoded as something other than text , or it's not UTF-8 format, it won't convert to a string. 如果数据编码为text以外的其他格式,或者不是UTF-8格式,则不会转换为字符串。

Answering: "Sometimes, cast NSData to String doesn't work." 回答:“有时,将NSData强制转换为String无效。”
Not all data is convertible to a particular string encoding. 并非所有数据都可以转换为特定的字符串编码。 In the case: 在这种情况下:

var str = String.init(data: bytes, encoding: NSUTF8StringEncoding)

there are a great number of bytes and byte sequences that have no valid UTF-8 character encoding. 有很多字节和字节序列没有有效的UTF-8字符编码。

Note: I don't speak Swift. 注意:我不会讲Swift。 This following code may not compile, but it should give you the main idea/logic behind it. 以下代码可能无法编译,但应为您提供背后的主要思想/逻辑。

The issue was because there NSData was incomplete (you receive them piece by piece and the buffer size may not be sufficient to handle the complete response at once), assuming that the bytes are really transformable to NSString according to the encoding used, as @zaph pointed out. 问题是因为那里的NSData不完整(您可以NSData接收它们,并且缓冲区大小可能不足以一次处理完整的响应), 前提是根据使用的编码,字节确实可以转换为NSString ,例如@zaph指出。 Simple example: Transform a UIImage into NSData using UIImageJPEGRepresentation() for example, and try to transform it into NSString using the wanted encoding, it may not be valid, or do the same with the stream of a video. 简单示例:例如,使用UIImageJPEGRepresentation()UIImage转换为NSData ,然后尝试使用所需的编码将其转换为NSString ,它可能无效,或者对视频流也是如此。

An example for our case: 我们的例子:
Full valid "Character": "1001", nothing with "10" nor "01". 完整有效的“字符”:“ 1001”,不带“ 10”或“ 01”的内容。
You receive "10" only. 您只收到“ 10”。 And if you convert it to NSString , it's nil because it's not valid. 如果将其转换为NSString ,则为nil,因为它无效。
Then, you receive "01". 然后,您收到“ 01”。 And if you convert it to NSString , it's nil because it's not valid. 如果将其转换为NSString ,则为nil,因为它无效。
So you have to read all the NSData before transforming it to NSString . 因此,您必须先读取所有NSData然后才能将其转换为NSString

So at the beginning, you can create a var finalData = NSMutableData.init() Then, each time you read the buffer, do: 因此,在开始时,您可以创建一个var finalData = NSMutableData.init()然后,每次读取缓冲区时,请执行以下操作:

var partialData = NSData.init(bytes: data, length: data.count)
finalData.appendData(partialData)

At the end, just transform finalData to String : 最后,只需将finalData转换为String

if let str = String(data:finalData, encoding: NSUTF8StringEncoding) {
    response = str
}

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

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