কোনও আইওএস অ্যাপ্লিকেশনে গ্লোবাল ধ্রুবকগুলি কোথায় সঞ্চয় করবেন?


111

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

// production
// static NSString* const baseUrl = "http://website.com/"

// testing
static NSString* const baseUrl = "http://192.168.0.123/"

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

String string = this.getString(R.string.someConstant);

আমি ভাবছিলাম যে আইওএস এসডিকে কনস্ট্যান্টগুলি সঞ্চয় করার জন্য কোনও অভিন্ন জায়গা রয়েছে কিনা। যদি তা না হয় তবে এটি করার জন্য অবজেক্টিভ-সি এর সেরা অনুশীলনটি কী?

উত্তর:


145

আপনি একটি করতে পারে

#define kBaseURL @"http://192.168.0.123/"

একটি "ধ্রুবক" শিরোনাম ফাইলটিতে বলুন constants.h। তাহলে কর

#include "constants.h"

আপনার এই ধ্রুবক প্রয়োজন প্রতিটি ফাইলের শীর্ষে।

এইভাবে, আপনি সংকলক পতাকার উপর নির্ভর করে সার্ভারগুলির মধ্যে স্যুইচ করতে পারেন:

#ifdef DEBUG
    #define kBaseURL @"http://192.168.0.123/"
#else
    #define kBaseURL @"http://myproductionserver.com/"
#endif

আমি "constants.h"পদ্ধতির ব্যবহার করে , staticভেরিয়েবলের ভিত্তিতে ঘোষণা করে #ifdef VIEW_CONSTANTS ... #endif। সুতরাং আমার কাছে একটি অ্যাপ্লিকেশন-ওয়াইড কনস্ট্যান্ট ফাইল রয়েছে, তবে আমার প্রতিটি কোড ফাইলের #defineকনস্ট্যান্টগুলির ফাইল- এর আগে অন্তর্ভুক্ত করার জন্য #includeকনস্ট্যান্টগুলির বিভিন্ন সেট রয়েছে (সমস্ত "সংজ্ঞায়িত তবে ব্যবহৃত নয়" সংকলক সতর্কতা বন্ধ করে দেয়)।

2
এই সমাধানটি নিয়ে আমি দুটি বিষয় নিয়ে এসেছি। প্রথমত, যখন আমি ব্যবহার করি, তখন #decalare" অবৈধ প্রিপ্রোসেসিং নির্দেশিকা ঘোষণা করুন " বলে একটি সংকলন ত্রুটি পেয়েছি । সুতরাং আমি পরিবর্তে এটি পরিবর্তন #define। অন্য সমস্যা ধ্রুবক ব্যবহার করা হয়। আমি এর সাথে আরেকটি ধ্রুবক তৈরি করতে চেয়েছিলাম static NSString* const fullUrl = [NSString stringWithFormat:@"%@%@", kbaseUrl, @"script.php"], তবে স্পষ্টতই একটি অভিব্যক্তি সহ কনসেন্ট তৈরি করা অবৈধ। আমি ত্রুটি পেয়েছি " প্রাথমিক উপাদান ধ্রুবক নয় "।
জোজো

1
@ সাইরিল অ্যান্ড্রয়েড অনুশীলন করা সত্যিই আকর্ষণীয়, এমন কিছু সম্ভাবনা রয়েছে যা আপনি iOS এ কল্পনা করতে পারেন নি! যাইহোক উত্তর দেওয়ার জন্য ধন্যবাদ
klefevre

8
কনসিড-টাইম চেকিং, এবং ডিবাগিং আরও ভাল কাজ করে - যেখানে # ডিফাইন সেখানে সম্ভব এর চেয়ে বেশি পছন্দ করুন।
আকস্মিক

2
@ অ্যানসোন ইয়াও সাধারণত যখন আমার সাথে ঘটে তখন আমি # #define kBaseURL @"http://192.168.0.123/";
ডিফাইন

168

ভাল, আপনি যে ইন্টারফেসের সাথে সম্পর্কিত তার ঘোষণাকে স্থানীয় করতে চান - অ্যাপ-ওয়াইড কনস্ট্যান্ট ফাইলটি ভাল জিনিস নয়।

পাশাপাশি, এটি extern NSString* constব্যবহার না করে কেবল একটি প্রতীক ঘোষণা করা আরও ভাল #define:


SomeFile.h

extern NSString* const MONAppsBaseUrl;

SomeFile.m

#import "SomeFile.h"

#ifdef DEBUG
NSString* const MONAppsBaseUrl = @"http://192.168.0.123/";
#else
NSString* const MONAppsBaseUrl = @"http://website.com/";
#endif

সি ++ সামঞ্জস্যপূর্ণ বাহ্যিক ঘোষণার বাদ দেওয়া ছাড়াও আপনি সাধারণত অ্যাপলের ওবজ-সি ফ্রেমওয়ার্কগুলিতে এটি দেখতে পাবেন।

যদি ধ্রুবকটি কেবল একটি ফাইল বা ফাংশনে দৃশ্যমান হওয়া দরকার তবে static NSString* const baseUrlআপনার *.mমধ্যে ভাল।


26
নিশ্চিত নয় যে কেন অনুমোদিত উত্তরটিতে # সংজ্ঞা - কনস্টের পক্ষে পক্ষে 40 টি ভোট রয়েছে সত্যই এটি আরও ভাল const
আকস্মিক

1
অবশ্যই কনস্ট্যান্ট এনএসএসআর্টিং # ডিফাইন এর চেয়ে ভাল, এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। # সংজ্ঞায়িত প্রতিটি সময় সংজ্ঞায়িত মানটি ব্যবহার করার সময় একটি নতুন স্ট্রিং তৈরি করে।
jbat100

1
@ jbat100 আমার মনে হয় না এটি একটি নতুন স্ট্রিং তৈরি করে। আমি মনে করি যে সংস্থাপকটি সনাক্ত করে যদি আপনার কোড একই স্ট্যাটিক স্ট্রিংটি 300,000 বার তৈরি করে এবং কেবল একবার এটি তৈরি করবে। @"foo"হিসাবে একই হয় না [[NSString alloc] initWithCString:"foo"]
অভি বেকার্ট

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

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

39

আমি বিশ্বব্যাপী ধ্রুবককে যেভাবে সংজ্ঞায়িত করি:


AppConstants.h

extern NSString* const kAppBaseURL;

AppConstants.m

#import "AppConstants.h"

#ifdef DEBUG
NSString* const kAppBaseURL = @"http://192.168.0.123/";
#else
NSString* const kAppBaseURL = @"http://website.com/";
#endif

তারপরে আপনার {$ অ্যাপ্লিকেশন} -প্রিফিক্স.পিচ ফাইলে:

#ifdef __OBJC__
  #import <UIKit/UIKit.h>
  #import <Foundation/Foundation.h>
  #import "AppConstants.h"
#endif

আপনি যদি কোনও সমস্যা অনুভব করেন তবে প্রথমে নিশ্চিত হয়ে নিন যে আপনার প্রাক্পম্পাইল প্রিফিক্স শিরোনাম বিকল্পটি NO তে সেট করা আছে।


5

আপনি স্ট্রিং ধ্রুবকগুলিও এর মতো করে তুলতে পারেন:

  #define kBaseURL @"http://myServer.com"
  #define kFullURL kBaseURL @"/api/request"

4

আমি মনে করি যে এটি করার অন্য একটি উপায়টি আরও সহজ এবং আপনি কেবল ফাইলগুলি এতে অন্তর্ভুক্ত করবেন, সমস্ত ফাইলগুলি .pch উপসর্গ ফাইলের মতো নয়:

#ifndef Constants_h
#define Constants_h

//Some constants
static int const ZERO = 0;
static int const ONE = 1;
static int const TWO = 2;

#endif /* Constants_h */

এর পরে আপনি যে শিরোনাম ফাইলটি চান তা এই হেডার ফাইলটি অন্তর্ভুক্ত করবেন। আপনি এটি নির্দিষ্ট ক্লাসের জন্য এটি শীর্ষক ফাইলে অন্তর্ভুক্ত করতে চান যা এতে অন্তর্ভুক্ত থাকতে চান:

#include "Constants.h"

আমার পরীক্ষায়, স্ট্যাটিক কনস্ট্যান্ট ধ্রুবকগুলি ডিবাগারে (এক্সকোডের এলএলডিবি) ব্যবহারযোগ্য নয়। "error: use of undeclared identifier .."
jk7

3
  1. আমি YOURPROJECT-Prefix.pch ফাইলটিতে গ্লোবাল ধ্রুবককে সংজ্ঞায়িত করি।
  2. #define BASEURl @"http://myWebService.appspot.com/xyz/xx"
  3. তারপরে BASEURL ব্যবহার করার জন্য প্রকল্পের যে কোনও জায়গায়:

    NSString *LOGIN_URL= [BASEURl stringByAppendingString:@"/users/login"];

আপডেট হয়েছে: এক্সকোড 6 এ আপনি আপনার প্রকল্পে তৈরি ডিফল্ট .pch ফাইল খুঁজে পাবেন না। সুতরাং আপনার প্রকল্পে .pch ফাইল সন্নিবেশ করতে দয়া করে Xcode 6 এ PCH ফাইলটি ব্যবহার করুন ।

আপডেটস: সুইফটের জন্য

  1. নতুন অ্যাপ্লিকেশন তৈরি করুন [শ্রেণিবিহীন খালি] বলুন [অ্যাপগ্লোবাল মেমবার্স]
  2. & এখনই সদস্য ঘোষণা / সংজ্ঞা দিন

    উদাহরণ:

    var STATUS_BAR_GREEN : UIColor  = UIColor(red: 106/255.0, green: 161/255.0, blue: 7/255.0, alpha: 1)  //
    1. আপনি যদি কোনও ক্লাসের ফাইলটিতে অ্যাপ্লিকেশন গ্লোবাল সদস্যকে সংজ্ঞায়িত করতে চান তবে অ্যাপলেলেগেট বা সিঙ্গলটন ক্লাস বা কোনও বলুন, প্রদত্ত সদস্যকে শ্রেণীর সংজ্ঞার উপরে ঘোষণা করুন

2

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

আমি মূল ডেটা অ্যাক্সেস, বা কিছু ব্যবসায়িক লজিকগুলিকে পুনরায় গোষ্ঠীকরণের জন্য ক্লাসগুলির বিশ্বব্যাপী উদাহরণ (প্রতিটি প্রকল্পের জন্য 1 বা 2, প্রয়োজন) ব্যবহার করি।

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

এটি এক দুর্দান্ত সহায়তা, অবজেক্ট ওরিয়েন্টেড এবং আপনার সমস্ত জিনিস একই স্থানে পাওয়ার একটি ভাল উপায়

কোডের কয়েকটি লাইন:

@interface RestaurantManager : NSObject
    +(id) sharedInstance;
    -(void)registerForTable:(NSNumber *)tableId;
@end 

এবং অবজেক্ট বাস্তবায়ন:

@implementation RestaurantManager

+ (id) sharedInstance {
    static dispatch_once_t onceQueue;

    dispatch_once(&onceQueue, ^{
        sharedInstance = [[self alloc] init];
        NSLog(@"*** Shared instance initialisation ***");
    });
    return sharedInstance;
}

-(void)registerForTable:(NSNumber *)tableId {
}
@end

এটি ব্যবহারের জন্য এটি সত্যিই সহজ:

[[রেস্তোঁরাযাত্রী শেয়ারড ইনস্ট্যান্স] নিবন্ধন ফরবেল টেবিল: [এনএস নাম্বারসংখ্যার সাথে: 10]]


3
এই নকশার প্যাটার্নটির প্রযুক্তিগত নাম সিঙ্গেলটন। en.wikedia.org/wiki/Singleton_ Pattern
বাসিল বার্ক

স্ট্যাটিক ডেটা (স্ট্যাটিক ক্লাস নয়) শেয়ারড ম্যানেজারে রাখা ভাল ধারণা নয়।
ওন্দন ওজকান

1

গৃহীত উত্তরের 2 টি দুর্বলতা রয়েছে। প্রথমত, অন্যরা নির্দেশিত হিসাবে ব্যবহারের হয়#define যা ডিবাগ করা শক্ত, তার পরিবর্তে extern NSString* const kBaseUrlকাঠামো ব্যবহার করুন । দ্বিতীয়ত, এটি ধ্রুবকগুলির জন্য একটি একক ফাইল সংজ্ঞায়িত করে। আইএমও, এটি ভুল কারণ বেশিরভাগ শ্রেণীর কাছে এই ধ্রুবকগুলিতে অ্যাক্সেসের প্রয়োজন হয় না বা তাদের সমস্ত অ্যাক্সেসের জন্য প্লাস ফাইলটি স্ফীত হয়ে যেতে পারে যদি সেখানে সমস্ত ধ্রুবক ঘোষণা করা হয়। আরও ভাল সমাধান হ'ল 3 টি বিভিন্ন স্তরে ধ্রুবককে মডিউলাইজ করা:

  1. সিস্টেম স্তর: SystemConstants.h বা AppConstants.h যা বিশ্বব্যাপী স্কোপগুলিতে ধ্রুবকদের বর্ণনা করে, যা সিস্টেমের যে কোনও শ্রেণি দ্বারা অ্যাক্সেস করা যেতে পারে। এখানে কেবলমাত্র সেই ধ্রুবকগুলিকে ঘোষণা করুন যা অবশ্যই সম্পর্কিত নয় এমন বিভিন্ন শ্রেণি থেকে অ্যাক্সেস করতে হবে।

  2. মডিউল / উপ-সিস্টেম স্তর: ModuleNameConstants.h ধ্রুবকগুলির একটি সেট বর্ণনা করে যা মডিউল / উপ-সিস্টেমের অভ্যন্তরে সম্পর্কিত শ্রেণীর সেটগুলির জন্য নির্দিষ্ট typ

  3. বর্গ স্তর: ধ্রুবকগুলি ক্লাসে থাকে এবং কেবল এটির দ্বারা ব্যবহৃত হয়।

শুধুমাত্র 1,2 টি প্রশ্নের সাথে সম্পর্কিত।


0

আমি আগে ব্যবহার করেছি এমন একটি পদ্ধতি হ'ল একটি ফাইল তৈরি করা Settings.plistএবং এটি NSUserDefaultsব্যবহারের পরে লঞ্চে লোড করা registerDefaults:। তারপরে আপনি নিম্নলিখিত বিষয়গুলি সহ এর সামগ্রীগুলি অ্যাক্সেস করতে পারবেন:

// Assuming you've defined some constant kMySettingKey.
[[NSUserDefaults standardUserDefaults] objectForKey:kMySettingKey];

যদিও আমি কোনও অ্যান্ড্রয়েড বিকাশ করি নি, মনে হচ্ছে এটি আপনার বর্ণিত স্ট্রিং রিসোর্স ফাইলের সাথে সাদৃশ্যপূর্ণ। একমাত্র ক্ষতি হ'ল আপনি প্রিপ্রসেসরটি সেটিংসের (যেমন DEBUGমোডে) মধ্যে পরিবর্তন করতে পারবেন না cess আমি মনে করি আপনি যদিও অন্য কোনও ফাইলে লোড করতে পারেন।

NSUserDefaults ডকুমেন্টেশন।


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

আমি মনে করি এই পদ্ধতির বেশ কিছু সুবিধা, সবচেয়ে গুরুত্বপূর্ণ হচ্ছে যে আপনার সেটিংস সঠিক ফরম্যাট (ফিরে রয়েছে NSString, NSNumberইত্যাদি)। অবশ্যই, আপনি #defineএকই জিনিসটি করতে মোড়তে পারেন তবে তারা সম্পাদনা করা এতটা সহজ নয়। plistসম্পাদনা ইন্টারফেস চমৎকার, অত্যধিক। :) আমি সম্মত হয়েছি যে সেখানে আপনাকে এনক্রিপশন কীগুলির মতো সুপার সিক্রেট স্টাফ না দেওয়া উচিত, আমি এমন ব্যবহারকারীদের সম্পর্কে খুব বেশি উদ্বিগ্ন নই যাঁরা এমন জায়গাগুলি ঘুরে বেড়াচ্ছেন should যদি তারা অ্যাপটি ভাঙেন তবে এটি তাদের নিজস্ব দোষ it's ।
ক্রিস ডবল

1
অবশ্যই, আমি আপনার যুক্তিগুলির সাথে একমত যেমন আপনি বলেছেন, আমি #defineসঠিক টাইপটি ফিরতে আমার গুলি আবদ্ধ করি , তবে আমি এই ধরণের ধ্রুবক ফাইলগুলি সম্পাদনা করতে অভ্যস্ত, যেহেতু আমি সর্বদা এই জাতীয় বৈশ্বিক ধ্রুবকগুলিকে পৃথক কনস্ট্যান্ট ফাইলে রাখতে শিখেছি, আমি পাস্কাল শিখার দিন থেকে ফিরে এসেছি back পুরানো ২66 তে :) এবং যে ব্যবহারকারী সর্বত্র ঘুরে বেড়াচ্ছেন, আমিও তাতে রাজি, এটি তাদের দোষ। সত্যিই এটি স্বাদের বিষয় মাত্র।
সিরিল

@ ক্রিস ডবল: না, অ্যান্ড্রয়েডের রিসোর্স ফাইলগুলি এনএসউসারডেফল্টগুলির সাথে সমান নয়। SharedPreferences এবং পছন্দগুলি হ'ল এনএসইউসারডেফাল্টগুলির এনড্রয়েড সমতুল্য (যদিও এনএসউসারডেফাল্টগুলির চেয়ে আরও শক্তিশালী)। অ্যান্ড্রয়েডের সংস্থানগুলি স্থানীয়করণ হিসাবে এবং অন্যান্য অনেক ব্যবহারের জন্য বিষয়বস্তু থেকে লজিককে পৃথক করার উদ্দেশ্যে।
এমআরডি

0

একটি সংখ্যার জন্য আপনি এটি পছন্দ মতো ব্যবহার করতে পারেন

#define MAX_HEIGHT 12.5

0

আমি একটি কনফিগারেশন অবজেক্ট ব্যবহার করব যা এ থেকে আরম্ভ হয় plist। অপ্রাসঙ্গিক বাহ্যিক স্টাফ দিয়ে অন্যান্য ক্লাসকে কেন বিরক্ত করবেন?

আমি eppz!settignsএই কারণে soley তৈরি । একটি থেকে ডিফল্ট মান অন্তর্ভুক্ত করার জন্য এনএসউসারডেফল্টগুলিতে সংরক্ষণের জন্য উন্নত তবে সহজ উপায়টি নিবন্ধটি দেখুন plist

এখানে চিত্র বর্ণনা লিখুন


সত্য। ওয়ার্ডপ্রেস কোনওভাবেই সমাধান করবেন না ...: / ... যাইহোক এই সরাসরি লিঙ্কটির সাথে যান blog.eppz.eu/?p=926 : ডি
গেরি বোরবস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.