আমি কীভাবে আমার আইফোন অ্যাপে এনএসইরর ব্যবহার করতে পারি?


228

আমি আমার অ্যাপ্লিকেশনটিতে ত্রুটিগুলি ধরাতে কাজ করছি এবং আমি এটি ব্যবহারের দিকে তাকাচ্ছি NSError। এটি কীভাবে ব্যবহার করতে হয় এবং কীভাবে এটি ব্যবহার করা যায় সে সম্পর্কে আমি কিছুটা বিভ্রান্ত।

আমি কীভাবে ব্যবহার করব তারপরে কীভাবে কেউ উদাহরণ দিতে পারেন NSError?

উত্তর:


473

ভাল, আমি সাধারণত যা করি তা হ'ল আমার পদ্ধতিগুলি যা রানটাইমের সময় ত্রুটি-বিচ্যুত হতে পারে কোনও NSErrorপয়েন্টারের রেফারেন্স নিতে পারে । যদি সেই পদ্ধতিতে আসলে কিছু ভুল হয়ে যায় তবে আমি NSErrorত্রুটি ডেটা সহ রেফারেন্সটি পপুলেট করতে পারি এবং পদ্ধতিটি থেকে শূন্য করতে পারি।

উদাহরণ:

- (id) endWorldHunger:(id)largeAmountsOfMonies error:(NSError**)error {
    // begin feeding the world's children...
    // it's all going well until....
    if (ohNoImOutOfMonies) {
        // sad, we can't solve world hunger, but we can let people know what went wrong!
        // init dictionary to be used to populate error object
        NSMutableDictionary* details = [NSMutableDictionary dictionary];
        [details setValue:@"ran out of money" forKey:NSLocalizedDescriptionKey];
        // populate the error object with the details
        *error = [NSError errorWithDomain:@"world" code:200 userInfo:details];
        // we couldn't feed the world's children...return nil..sniffle...sniffle
        return nil;
    }
    // wohoo! We fed the world's children. The world is now in lots of debt. But who cares? 
    return YES;
}

তারপরে আমরা এই পদ্ধতিটি ব্যবহার করতে পারি। এমনকি পদ্ধতিটি শূন্য না হলে ত্রুটি অবজেক্টটি পরীক্ষা করার জন্য বিরক্ত করবেন না:

// initialize NSError object
NSError* error = nil;
// try to feed the world
id yayOrNay = [self endWorldHunger:smallAmountsOfMonies error:&error];
if (!yayOrNay) {
   // inspect error
   NSLog(@"%@", [error localizedDescription]);
}
// otherwise the world has been fed. Wow, your code must rock.

আমরা ত্রুটিটি অ্যাক্সেস করতে পেরেছিলাম localizedDescriptionকারণ আমরা এর জন্য একটি মান সেট করেছি NSLocalizedDescriptionKey

আরও তথ্যের জন্য সেরা জায়গা অ্যাপলের ডকুমেন্টেশন । এটা সত্যিই ভাল।

কোকো ইজ মাই গার্লফ্রেন্ড সম্পর্কে একটি দুর্দান্ত, সহজ টিউটোরিয়ালও রয়েছে ।


37
এটি সর্বকালের মজার উদাহরণ,

যদিও এআরসি মধ্যে কিছু বিষয় আছে এবং ভোটদান এই একটি বেশ ভালো উত্তর হল, idএকটি থেকে BOOL। যে কোনও সামান্য এআরসি সামঞ্জস্যপূর্ণ প্রকরণটি অনেক প্রশংসিত হবে।
এনএসটিজে

6
@ টমজওয়েট যদি আমরা বিশ্ব ক্ষুধা শেষ করতে সক্ষম না হয়ে থাকি তবে অ্যাপল আমাদের কেবলমাত্র নতুন এআরসি বিশ্বে স্থানান্তরিত করতে বাধ্য করেছিলেন বলে আমি সত্যিই খুব খারাপ হয়ে যাব।
মানব

1
রিটার্ন টাইপ হতে পারে BOOLNOত্রুটির ক্ষেত্রে ফিরে আসুন এবং রিটার্ন মানটি পরীক্ষা করার পরিবর্তে কেবল পরীক্ষা করুন error। যদি nilএগিয়ে যান, যদি != nilএটি পরিচালনা করুন।
গ্যাব্রিয়েল পেট্রোনেলা

8
-1: আপনার সত্যিকারের কোডটি অন্তর্ভুক্ত করা দরকার যা যাচাই করে **errorনি। অন্যথায় প্রোগ্রামটি সম্পূর্ণরূপে বন্ধুত্বপূর্ণ এমন একটি ত্রুটি ছুঁড়ে দেবে এবং যা ঘটছে তা তা প্রকাশ করে না।
ফ্রিএএসআইনবিয়ার

58

আমি আমার সাম্প্রতিক বাস্তবায়নের ভিত্তিতে আরও কিছু পরামর্শ যুক্ত করতে চাই। আমি অ্যাপলের কিছু কোড দেখেছি এবং আমার ধারণা আমার কোডটিও একইভাবে আচরণ করে।

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


আমি 1 টি শিরোনাম তৈরির প্রস্তাব দিচ্ছি যা আপনার ডোমেনের সমস্ত ত্রুটির (যেমন অ্যাপ্লিকেশন, গ্রন্থাগার, ইত্যাদি ..) এর ওভারভিউ হবে। আমার বর্তমান শিরোনামটি দেখতে এমন দেখাচ্ছে:

FSError.h

FOUNDATION_EXPORT NSString *const FSMyAppErrorDomain;

enum {
    FSUserNotLoggedInError = 1000,
    FSUserLogoutFailedError,
    FSProfileParsingFailedError,
    FSProfileBadLoginError,
    FSFNIDParsingFailedError,
};

FSError.m

#import "FSError.h" 

NSString *const FSMyAppErrorDomain = @"com.felis.myapp";

ত্রুটির জন্য উপরের মানগুলি ব্যবহার করার সময়, অ্যাপল আপনার অ্যাপ্লিকেশনটির জন্য কিছু প্রাথমিক স্ট্যান্ডার্ড ত্রুটি বার্তা তৈরি করবে। নিম্নলিখিতগুলির মতো একটি ত্রুটি তৈরি করা যেতে পারে:

+ (FSProfileInfo *)profileInfoWithData:(NSData *)data error:(NSError **)error
{
    FSProfileInfo *profileInfo = [[FSProfileInfo alloc] init];
    if (profileInfo)
    {
        /* ... lots of parsing code here ... */

        if (profileInfo.username == nil)
        {
            *error = [NSError errorWithDomain:FSMyAppErrorDomain code:FSProfileParsingFailedError userInfo:nil];            
            return nil;
        }
    }
    return profileInfo;
}

error.localizedDescriptionউপরের কোডটির জন্য স্ট্যান্ডার্ড অ্যাপল-উত্পাদিত ত্রুটি বার্তা ( ) নীচের মত দেখাবে:

Error Domain=com.felis.myapp Code=1002 "The operation couldn’t be completed. (com.felis.myapp error 1002.)"

উপরোক্ত বিকাশকারীটির জন্য ইতিমধ্যে বেশ সহায়ক, বার্তাটি সেই ডোমেনটি প্রদর্শন করে যেখানে ত্রুটি ঘটেছে এবং সম্পর্কিত ত্রুটি কোড। ত্রুটি কোডটির 1002অর্থ কী , তবে শেষ ব্যবহারকারীদের কোনও ধারণা নেই , সুতরাং এখন প্রতিটি কোডের জন্য আমাদের কিছু সুন্দর বার্তা কার্যকর করতে হবে।

ত্রুটি বার্তাগুলির জন্য আমাদের স্থানীয়করণকে মাথায় রাখতে হবে (আমরা এখনই স্থানীয়করণ করা বার্তাগুলি বাস্তবায়ন করি না)। আমি আমার বর্তমান প্রকল্পে নিম্নলিখিত পদ্ধতিটি ব্যবহার করেছি:


1) একটি stringsফাইল তৈরি করুন যাতে ত্রুটি থাকবে। স্ট্রিং ফাইলগুলি সহজেই স্থানীয়করণযোগ্য। ফাইলটি নিম্নলিখিতগুলির মতো দেখতে পারে:

FSError.strings

"1000" = "User not logged in.";
"1001" = "Logout failed.";
"1002" = "Parser failed.";
"1003" = "Incorrect username or password.";
"1004" = "Failed to parse FNID."

2) স্থানীয় ত্রুটি বার্তায় পূর্ণসংখ্যার কোড রূপান্তর করতে ম্যাক্রোগুলি যুক্ত করুন। আমি আমার কনস্ট্যান্টস + ম্যাক্রোস ফাইল ফাইলটিতে 2 টি ম্যাক্রো ব্যবহার করেছি। MyApp-Prefix.pchসুবিধার জন্য আমি এই ফাইলটি সর্বদা উপসর্গ শিরোনামে অন্তর্ভুক্ত করি ।

ধ্রুবক + + Macros.h

// error handling ...

#define FS_ERROR_KEY(code)                    [NSString stringWithFormat:@"%d", code]
#define FS_ERROR_LOCALIZED_DESCRIPTION(code)  NSLocalizedStringFromTable(FS_ERROR_KEY(code), @"FSError", nil)

3) এখন একটি ত্রুটি কোডের উপর ভিত্তি করে কোনও ব্যবহারকারী বান্ধব ত্রুটি বার্তা প্রদর্শন করা সহজ। একটি উদাহরণ:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" 
            message:FS_ERROR_LOCALIZED_DESCRIPTION(error.code) 
            delegate:nil 
            cancelButtonTitle:@"OK" 
            otherButtonTitles:nil];
[alert show];

9
দুর্দান্ত উত্তর! তবে স্থানীয় বর্ণিত বিবরণটি যেখানে এটি ব্যবহার করে সেখানে ব্যবহারকারীর তথ্য অভিধানে রাখবেন না? [এনএসইরর ত্রুটিটিডমোইন সহ: এফএসমাইএপিআরআরডোমাইন কোড: FSProfileParsingFidedError ব্যবহারকারীকর্মীআইএনফো: @ S NSLocalizedDescriptKey: FS_ERROR_LOCALIZED_DESCRIPTION (ত্রুটি কোড)}];
রিচার্ড ভেনেবল

1
আমার কোনও স্ট্রিং ফাইল রাখা উচিত এমন কোনও নির্দিষ্ট জায়গা আছে? FS_ERROR_LOCALIZED_DESCRIPTION () থেকে আমি কেবল নম্বর (ত্রুটি কোড) পাচ্ছি।
হুগি

@ হুগি: আপনি কী বলতে চাইছেন তা সত্য নয়। আমি সাধারণত এই ম্যাক্রোগুলি ব্যবহার করি যা আমি পুরো অ্যাপ্লিকেশন জুড়ে একটি ফাইল বলে Constants+Macros.hএবং যে ফাইলটি প্রিফিক্স শিরোনামে ( .pchফাইল) আমদানি করি তাই এটি সর্বত্র উপলব্ধ। যদি আপনি বোঝাতে চান যে আপনি কেবল 2 ম্যাক্রোগুলির মধ্যে 1 ব্যবহার করছেন তবে এটি কার্যকর হতে পারে। সম্ভবত থেকে রুপান্তরের intজন্য NSStringযদিও আমি এই পরীক্ষা করা হয়েছে, সত্যিই প্রয়োজন হয় না।
ওল্ফগ্যাং শ্রেরস

@ হুগি: ওহ, আমি আপনাকে এখন বুঝতে পেরেছি বলে মনে করি। স্ট্রিংগুলি স্থানীয়করণযোগ্য ফাইল ( .stringsফাইল) এ থাকা উচিত, যেহেতু অ্যাপল এর ম্যাক্রোটি দেখবে। NSLocalizedStringFromTableএখানে ব্যবহার সম্পর্কে পড়ুন : developer.apple.com/library/mac/docamentation/cocoa/conceptual/…
ওল্ফগাং শ্রিয়রস

1
@ হুগি: হ্যাঁ, আমি স্থানীয়করণের স্ট্রিং টেবিলগুলি ব্যবহার করেছি। ম্যাক্রোতে কোড কল করা FS_ERROR_LOCALIZED_DESCRIPTIONকোনও ফাইলে স্থানীয়করণযোগ্য স্ট্রিং পরীক্ষা করে FSError.strings। এটি .stringsযদি আপনার কাছে বিদেশী হয় তবে আপনি ফাইলগুলিতে অ্যাপলের স্থানীয়করণ গাইডটি পরীক্ষা করে দেখতে চাইতে পারেন ।
ওল্ফগ্যাং শ্রেরস

37

দুর্দান্ত উত্তর অ্যালেক্স। একটি সম্ভাব্য সমস্যা হ'ল ন্যূনসামগ্রী। এনএসইরর অবজেক্ট তৈরি এবং ফিরিয়ে দেওয়ার বিষয়ে অ্যাপলের রেফারেন্স

...
[details setValue:@"ran out of money" forKey:NSLocalizedDescriptionKey];

if (error != NULL) {
    // populate the error object with the details
    *error = [NSError errorWithDomain:@"world" code:200 userInfo:details];
}
// we couldn't feed the world's children...return nil..sniffle...sniffle
return nil;
...

30

উদ্দেশ্য গ

NSError *err = [NSError errorWithDomain:@"some_domain"
                                   code:100
                               userInfo:@{
                                           NSLocalizedDescriptionKey:@"Something went wrong"
                               }];

সুইফট 3

let error = NSError(domain: "some_domain",
                      code: 100,
                  userInfo: [NSLocalizedDescriptionKey: "Something went wrong"])

9

নিম্নলিখিত টিউটোরিয়াল রেফারেন্স করুন

আমি আশা করি এটি আপনার পক্ষে সহায়ক হবে তবে আপনাকে এনএসইররের ডকুমেন্টেশন পড়তে হবে

এটি খুব আকর্ষণীয় লিঙ্কটি আমি পেয়েছি সম্প্রতি ত্রুটি হ্যান্ডলিং


3

আমি অ্যালেক্স এবং জেলমেঞ্জবোনিনি'র বক্তব্যটির দুর্দান্ত উত্তরটি সংক্ষেপে চেষ্টা করার চেষ্টা করব, একটি সংশোধন যুক্ত করে যা সমস্ত কিছুকে এআরসি সামঞ্জস্য করে তুলবে (এখনও পর্যন্ত এটি আসেনি যেহেতু আপনাকে ফিরে আসা উচিত id, যেহেতু এটি "কোনও বস্তু", তবে BOOLএটি কোনও বস্তু নয়) টাইপ)।

- (BOOL) endWorldHunger:(id)largeAmountsOfMonies error:(NSError**)error {
    // begin feeding the world's children...
    // it's all going well until....
    if (ohNoImOutOfMonies) {
        // sad, we can't solve world hunger, but we can let people know what went wrong!
        // init dictionary to be used to populate error object
        NSMutableDictionary* details = [NSMutableDictionary dictionary];
        [details setValue:@"ran out of money" forKey:NSLocalizedDescriptionKey];
        // populate the error object with the details
        if (error != NULL) {
             // populate the error object with the details
             *error = [NSError errorWithDomain:@"world" code:200 userInfo:details];
        }
        // we couldn't feed the world's children...return nil..sniffle...sniffle
        return NO;
    }
    // wohoo! We fed the world's children. The world is now in lots of debt. But who cares? 
    return YES;
}

এখন আমাদের মেথড কলের রিটার্ন মানটি পরীক্ষা করার পরিবর্তে, আমরা errorএখনও পরীক্ষা করে দেখছি nil। এটি না হলে আমাদের সমস্যা আছে have

// initialize NSError object
NSError* error = nil;
// try to feed the world
BOOL success = [self endWorldHunger:smallAmountsOfMonies error:&error];
if (!success) {
   // inspect error
   NSLog(@"%@", [error localizedDescription]);
}
// otherwise the world has been fed. Wow, your code must rock.

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

3

আমি দেখেছি যে অন্য একটি নকশার প্যাটার্নে ব্লক ব্যবহার করা জড়িত, যা বিশেষত কার্যকর যখন কোনও পদ্ধতি অ্যাসিনক্রোনালি চালিত হয় run

বলুন যে আমাদের নীচের ত্রুটি কোডগুলি সংজ্ঞায়িত করা হয়েছে:

typedef NS_ENUM(NSInteger, MyErrorCodes) {
    MyErrorCodesEmptyString = 500,
    MyErrorCodesInvalidURL,
    MyErrorCodesUnableToReachHost,
};

আপনি আপনার পদ্ধতিটি এমনভাবে সংজ্ঞায়িত করবেন যা ত্রুটি বাড়িয়ে তুলতে পারে:

- (void)getContentsOfURL:(NSString *)path success:(void(^)(NSString *html))success failure:(void(^)(NSError *error))failure {
    if (path.length == 0) {
        if (failure) {
            failure([NSError errorWithDomain:@"com.example" code:MyErrorCodesEmptyString userInfo:nil]);
        }
        return;
    }

    NSString *htmlContents = @"";

    // Exercise for the reader: get the contents at that URL or raise another error.

    if (success) {
        success(htmlContents);
    }
}

এবং তারপরে আপনি যখন এটি কল করবেন তখন আপনাকে এনএসইরর অবজেক্টটি ঘোষণার (কোড সমাপ্তি এটি আপনার জন্য করবে), বা প্রত্যাবর্তনের মানটি পরীক্ষা করার বিষয়ে চিন্তা করার দরকার নেই। আপনি কেবল দুটি ব্লক সরবরাহ করতে পারেন: একটি ব্যতিক্রম থাকলে কল হবে এবং এটি সফল হলে কল হবে:

[self getContentsOfURL:@"http://google.com" success:^(NSString *html) {
    NSLog(@"Contents: %@", html);
} failure:^(NSError *error) {
    NSLog(@"Failed to get contents: %@", error);
    if (error.code == MyErrorCodesEmptyString) { // make sure to check the domain too
        NSLog(@"You must provide a non-empty string");
    }
}];

0

ঠিক আছে এটি প্রশ্নের ক্ষেত্র থেকে কিছুটা দূরে তবে যদি এনএসইররারের কাছে আপনার কাছে বিকল্প না থাকে তবে আপনি সর্বদা নিম্ন স্তরের ত্রুটি প্রদর্শন করতে পারেন:

 NSLog(@"Error = %@ ",[NSString stringWithUTF8String:strerror(errno)]);

0
extension NSError {
    static func defaultError() -> NSError {
        return NSError(domain: "com.app.error.domain", code: 0, userInfo: [NSLocalizedDescriptionKey: "Something went wrong."])
    }
}

যা আমি NSError.defaultError()যখনই ব্যবহার করতে পারি যখনই আমার বৈধ ত্রুটিযুক্ত বস্তু নেই।

let error = NSError.defaultError()
print(error.localizedDescription) //Something went wrong.
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.