ইউটিএফ -8 এনকোডযুক্ত এনএসডিটা এনএসএসটিংয়ে রূপান্তর করুন


567

আমার NSDataউইন্ডোজ সার্ভার থেকে ইউটিএফ -8 এনকোড হয়েছে এবং আমি এটি NSStringআইফোনের জন্য রূপান্তর করতে চাই । যেহেতু ডেটাতে অক্ষর রয়েছে (একটি ডিগ্রী প্রতীকের মতো) যার উভয় প্ল্যাটফর্মে আলাদা মান রয়েছে, তাই আমি কীভাবে ডেটাগুলিকে স্ট্রিংয়ে রূপান্তর করব?


16
ইউটিএফ -8 সর্বত্র ইউটিএফ -8। এটি একবার ইউটিএফ -8 হয়ে গেলে, বিভিন্ন প্ল্যাটফর্মগুলির জন্য আলাদা মান নেই। এটি এর পুরো বিষয়টি।
gnasher729

উত্তর:


1155

যদি ডেটা নাল-সমাপ্ত না হয়, আপনার ব্যবহার করা উচিত -initWithData:encoding:

NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];

যদি ডেটা নাল-টার্মিনেট করা হয় তবে আপনার পরিবর্তে -stringWithUTF8String:অতিরিক্তটি এড়াতে ব্যবহার করা উচিত \0

NSString* newStr = [NSString stringWithUTF8String:[theData bytes]];

(মনে রাখবেন যে ইনপুটটি সঠিকভাবে ইউটিএফ-8-এনকোড করা না হলে আপনি পাবেন nil))


সুইফ্ট বৈকল্পিক:

let newStr = String(data: data, encoding: .utf8)
// note that `newStr` is a `String?`, not a `String`.

যদি ডেটা নাল-টার্মিনেট করা হয় তবে আপনি যেতে পারবেন নিরাপদ উপায় যা সেই নাল চরিত্রটিকে সরিয়ে দেয় বা উপরের উদ্দেশ্য-সি সংস্করণের মতো অনিরাপদ উপায়।

// safe way, provided data is \0-terminated
let newStr1 = String(data: data.subdata(in: 0 ..< data.count - 1), encoding: .utf8)
// unsafe way, provided data is \0-terminated
let newStr2 = data.withUnsafeBytes(String.init(utf8String:))

5
সতর্ক থেকো!! যদি স্ট্রিংউইথএফ 8 স্ট্রিং ব্যবহার করে থাকেন তবে এটিকে নুল আর্গুমেন্টটি পাস করবেন না বা এটি ব্যতিক্রম করবে
জেসনজ

31
এটি মনে রাখবেন: "স্ট্রিংউইথআউটএফ 8 স্ট্রিং:" ব্যবহার করার সময় কোনও স্ট্রিং নাল-টার্মিনেট হয় না, ফলাফলটি অনাকাঙ্ক্ষিত!
বেরিক

2
উভয় সমাধান আমার জন্য শূন্য।
হুসেন

1
আপনার এনএসডিটা নাল-টার্মিনেটেড কিনা তা আপনি কীভাবে জানবেন? টম হ্যারিংটনের উত্তর এখানে দেখুন: স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 27935054/… । আমার অভিজ্ঞতায়, কখনই এনএসডিটা হয় নাল-সমাপ্ত বা ধরে নেওয়া উচিত নয়: এটি একটি পরিচিত সংস্থার থেকে অন্যটিতে স্থানান্তরিত হতে পারে এমনকি পরিচিত সার্ভার থেকেও আলাদা হতে পারে।
এলিস ভ্যান লুইজ

1
লিঙ্কের জন্য ধন্যবাদ আমি যুক্তি দিচ্ছি যে যদি সংক্রমণিত তথ্যগুলি এলোমেলোভাবে নাল-টার্মিনেট করা যায় বা না তবে প্রোটোকলটি সংজ্ঞায়িত হয়।
কেনেটিমে

28

আপনি এই পদ্ধতি কল করতে পারে

+(id)stringWithUTF8String:(const char *)bytes.

27
কেবল যদি ডেটা নাল-টার্মিনেট হয়। যা এটি নাও হতে পারে (এবং বাস্তবে সম্ভবত তা হয় না)।
ইভান ভুইকা

আমি জানি না কেন পৃথিবীতে এটি নন-টার্মিনেটেড স্ট্রিংগুলিতে ভেঙে পড়বে তা দেখে কীভাবে NSDataজানে যে এর কতগুলি বাইট রয়েছে ...
ক্লডিউ

5
@ ক্লাউডিউ, আপনি কোনও এনএসডিটা অবজেক্টে পাস করছেন না, আপনি এটিকে [ডেটা বাইটস] দিয়ে প্রাপ্ত একটি (কনস্টের চর *) দিচ্ছেন, যা কেবলমাত্র পয়েন্টার, কোনও আকারের তথ্য নয়। সুতরাং এটি ডেটা ব্লক করে এটি অবশ্যই বাতিল করতে হবে। ডকুমেন্টেশন দেখুন, এটি স্পষ্টভাবে বলে।
jbat100

1
@ jbat100: অবশ্যই আমি পরিষ্কার ছিল না। আমি বোঝাতে চেয়েছি, নন-নল-টার্মিনেটেড NSDataথেকে কোনও NSString(কেনেটিএম এর উত্তর দেখুন) যেতে পারার সম্ভাবনা রয়েছে, আমি অবাক হয়েছি +(id)stringWithUTF8Data:(NSData *)dataযে এটি ঠিক কাজ করে না।
ক্লদিউ

স্ট্রিংউইথএফ 8 ডেটা, সেইজন্য আমাদের বেশিরভাগই একটি এনএসএসস্ট্রিং + ফু বিভাগ তৈরি করে পদ্ধতিটি তৈরি করে।
উইলিয়াম কর্নিয়ুক

19

আমি এটিকে কম বিরক্তিকর করতে বিনীতভাবে একটি বিভাগ জমা দিচ্ছি:

@interface NSData (EasyUTF8)

// Safely decode the bytes into a UTF8 string
- (NSString *)asUTF8String;

@end

এবং

@implementation NSData (EasyUTF8)

- (NSString *)asUTF8String {
    return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];    
}

@end

(মনে রাখবেন আপনি যদি আরসি ব্যবহার না করে থাকেন তবে আপনার autoreleaseসেখানে একটি দরকার হবে))

এখন ভীতিজনকভাবে ভার্বোজের পরিবর্তে:

NSData *data = ...
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

আপনি করতে পারেন:

NSData *data = ...
[data asUTF8String];

18

স্ট্রিং থেকে ডেটা এবং স্ট্রিংয়ে ফিরে সুইফট সংস্করণ:

এক্সকোড 10.1 • সুইফট 4.2.1

extension Data {
    var string: String? {
        return String(data: self, encoding: .utf8)
    }
}

extension StringProtocol {
    var data: Data {
        return Data(utf8)
    }
}

extension String {
    var base64Decoded: Data? {
        return Data(base64Encoded: self)
    }
}

খেলার মাঠ

let string = "Hello World"                                  // "Hello World"
let stringData = string.data                                // 11 bytes
let base64EncodedString = stringData.base64EncodedString()  // "SGVsbG8gV29ybGQ="
let stringFromData = stringData.string                      // "Hello World"

let base64String = "SGVsbG8gV29ybGQ="
if let data = base64String.base64Decoded {
    print(data)                                    //  11 bytes
    print(data.base64EncodedString())              // "SGVsbG8gV29ybGQ="
    print(data.string ?? "nil")                    // "Hello World"
}

let stringWithAccent = "Olá Mundo"                          // "Olá Mundo"
print(stringWithAccent.count)                               // "9"
let stringWithAccentData = stringWithAccent.data            // "10 bytes" note: an extra byte for the acute accent
let stringWithAccentFromData = stringWithAccentData.string  // "Olá Mundo\n"

16

কখনও কখনও, অন্যান্য উত্তরের পদ্ধতিগুলি কার্যকর হয় না। আমার ক্ষেত্রে, আমি আমার আরএসএ প্রাইভেট কী দিয়ে একটি স্বাক্ষর তৈরি করছি এবং ফলাফলটি এনএসডিটা। আমি দেখেছি এটি কাজ করে বলে মনে হচ্ছে:

উদ্দেশ্য গ

NSData *signature;
NSString *signatureString = [signature base64EncodedStringWithOptions:0];

দ্রুতগতি

let signatureString = signature.base64EncodedStringWithOptions(nil)

কীভাবে সেই স্ট্রিংটি এনএসটাটাতে পাবেন?
দর্শনা কুঞ্জাদিয়া

1
@DarshanKunjadiya: উদ্দেশ্য সি : [[NSData alloc] initWithBase64EncodedString:signatureString options:0]; সুইফট : NSData(base64EncodedString: str options: nil)
মাইকেহো

1

কেবল সংক্ষেপে বলতে গেলে, এখানে একটি সম্পূর্ণ উত্তর আমার পক্ষে কাজ করেছিল।

আমার সমস্যাটি ছিল যখন আমি ব্যবহার করি

[NSString stringWithUTF8String:(char *)data.bytes];

আমি যে স্ট্রিংটি পেয়েছিলাম তা অনুমানযোগ্য ছিল: প্রায় 70% এর মধ্যে এটি প্রত্যাশিত মানটি ধারণ করে, তবে প্রায়শই এটির ফলাফল হয় Null বা এর থেকেও খারাপ: স্ট্রিংয়ের শেষে আবর্জনা।

কিছু খননের পরে আমি স্যুইচ করলাম ched

[[NSString alloc] initWithBytes:(char *)data.bytes length:data.length encoding:NSUTF8StringEncoding];

এবং প্রতিবার প্রত্যাশিত ফলাফল পেয়েছি।


এটি গুরুত্বপূর্ণ যে আপনি বুঝতে পেরেছেন <i> কেন </ i> আপনি 'আবর্জনা' ফলাফল পেয়েছেন।
এডগার অ্যার্টিওনিয়ান

1

সুইফট 5 Stringএর সাহায্যে আপনি ইউটিএফ -8 ব্যবহার করে একটি দৃষ্টান্তকে init(data:encoding:)রূপান্তর করতে একটি প্রারম্ভিক ব্যবহার করতে পারেন । নিম্নলিখিত ঘোষণা আছে:DataStringinit(data:encoding:)

init?(data: Data, encoding: String.Encoding)

Stringপ্রদত্ত এনকোডিং ব্যবহার করে প্রদত্ত ডেটাটিকে ইউনিকোড অক্ষরে রূপান্তর করে একটি সূচনা ফেরত দেয় ।

নিম্নলিখিত খেলার মাঠের কোডটি এটি কীভাবে ব্যবহার করবেন তা দেখায়:

import Foundation

let json = """
{
"firstName" : "John",
"lastName" : "Doe"
}
"""

let data = json.data(using: String.Encoding.utf8)!

let optionalString = String(data: data, encoding: String.Encoding.utf8)
print(String(describing: optionalString))

/*
 prints:
 Optional("{\n\"firstName\" : \"John\",\n\"lastName\" : \"Doe\"\n}")
*/
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.