السبت، 20 نوفمبر 2010

عالم آبل: يوم لا ينسى

عالم آبل: يوم لا ينسى

Link to عالم آبل

يوم لا ينسى

Posted: 20 Nov 2010 06:54 AM PST

هذه التدوينة ليست عن خبر وصول فرقة البيتلز ” الخنافس ” إلى متجر آيتونز و لكنها تدوينة عن ما فعلته آبل إذاء هذه الصفقة

هذه ليست فقط صفحة آبل الرئيسية و التي أصبحت كلها تحتوي الخبر نعم لا ماكبوك أير، لا ايبود – خاصة على اقتراب موسم الاجازات – بل كلها خنافس !

لست هنا لأخوض في مدى شهرة و نجاح هذه الفرقة لكن يكفيني أن أقول أنها أنجح و أشهر فرقة في تاريخ البشرية، تجاريا على الأقل.

لكنها ليست على هذه الشهرة هنا في المنطقة العربية و خاصة منطقة الخليج العربي و لكنها فرقة ذائعة الصيت في البلاد التي تدعم الفن المسموع و المرئي و طبعا على رأسها مصر و شهرتها وسط أجيال السبعينيات مهولة فلا يكاد  يوجد أحد كانت فترة شبابه في هذه الفترة ولا يعرف هذه الفرقة (أشبه بمايكل جاكسون بالنسبة لجيل التسعينات في الشرق الأوسط عامة) خاصة ارتباطهم بالشعر الطويل حتى أصبح يقال على من يطلق شعر رأسه ” أنت هتعمل فيها خنفس؟ ” !!

أذكر هذه المعلومات فقد لأؤكد على مدى شهرة هذه الفرقة .. فإذا كان هذا نجاحها في بلد لا ينطق لغتهم الأم فلك أن تتخيل نجاحهم في بلدانهم خاصة ارتباطهم بالثورة الاجتماعية في أمريكا في الستينيات و حرب فيتنام و الحرب الباردة طبعا بإمكانك التزود بالمزيد من المعلومات عنهم في ويكيبيديا.

و بالنسبة لآبل، فإن ستيف جوبز يستخدم نموذج عمل البيتلز أو ما يطلق عليه Business Model لذا فهم ليسوا مجرد مغنيين و لكنهم رجال أعمال من خلف الستار فالغناء رسالة و عمل (بغض النظر على ما يحدث الآن على الساحه الفنية العربية) خاصة أثناء مرور البلاد في حروب و ستيف جوبز كان معجب بهذا النموذج حتى أنه قال بلسانه :

طريقتي في العمل هي البيتلز، فقد كانو أربع أشخاص يحسنوا تعاملهم مع ميولهم السلبية توازنوا مع بعضهم البعض و أصبح المجموع أكبر من مجموع الأجزاء و هذه هي الطريقة التي أرى بها العمل الأشياء العظيمة في العمل لا تتم بواسطة شخص واحد و إنما تتم بواسطة فريق من الناس

و الآن، هل تريد مثالا على أن آبل لسيت كأي شركة أخرى ؟! إعتبر هذه الحادثة إجابة هذا السؤال.

فالصفحة الرئيسية لأي شركة هي أغلى ما تملك (على الأقل من الناحية التسويقية) و الآن و لسبب واحد قامت آبل بإزالة جميع الرسائل الدعائية لمنتجاتها من العتاد و البرمجيات .. خاصة على اقتراب الموسم الأكثر مبيعا في السنة .

حسنا، ربما ليس الموضوع مجرد حب لهذه الفرقة و لكنها دعاية لأن آبل تتمنى ربح أموال طائلة من وراء هذه الصفقة و ربما كانت هذه الخطوة من إحدى بنود إتمام الصفقة !

هذه ليست المرة الأولى التي تقوم فيها آبل بتخصيص صفحاتها الرئيسية لرسالة أكبر من منتجاتها .. مجرد حب لموضوع و كالعادة جاءت على حساب التضحية بمنتجاتهم !!

فقد كان هناك صور تذكارية لأعضاء مجلس الإدارة المتوفين مثل Jerome York في بداية هذا العام .. و George Harrison – 2001.. و Rosa Parks – 2005 .. و Gregory Hines – 2003 في الصفحة الرئيسية .. و لقد ظلت الرسائل الدعائية بالأسفل كما هي !!

و هذا و إن كان يدل على شيء، فهو يدل على أن شركة آبل تتصرف تصرفات شخص و ليست شركة (باعتقادي ليس بأول مرة) .. و من ناحية العلامة التجارية – ذلك شيء جيد- و هذا سبب من أكبر الأسباب في جعل آبل مرتبطة عاطفيا بعملائها .. عبر التعبير عن نفسها .. و لكن ليس دائما بالطريقة المناسبة !!

فقد أخطأت آبل عندما اختارت كلمات مثل (غدا مجرد يوم آخر.. لن تنساه أبدا) (Tomorrow is just another day, That you’ll never forget) .. فهي بمثابة الجملة الشهيرة (One more thing) لستيف جوبز فلو احتفظوا بهذه الجملة للإعلان عن خدمة للآي تونز أكثر تشويقا  مثل النسخة السحابية من الأي تونز لكي يصبح خزانة متنقلة لموسيقاك .. على الأقل لكان الأمر هين !

و بالتأكيد إذا كنت من عشاق هذه الفرقة، فأنا على يقين أنك تمتلك معظم أو جميع ألبوماتهم بالفعل في مكتبتك الموسيقية، خاصة أنها متوفرة بالفعل في صورة رقمية (و كالعادة بسعر أقل من ما هو موجود على متجر آي تونز الآن)

كما أنها اختارت اللعب بالكلمات بذكر كلمات أغانيهم، حتى عندما أعلن ستيف الخبر قام باختيار اسم إحدى أشهر أغانيهم (The Long and Winding Road) و لكن إختيارهم في الصفحة الرئيسية إحتوى الكلمات الخاطئة فكلمات (Is Just Another Day) هي إحدى أشهر أغاني Paul McCartney في أوائل  ألبوماته المنفردة و الموجودة في أغنية (Another Day) و ليست إحدى أعمال البيتلز !!

و لكن على الأقل أصبح الآن المتجر شبه مكتمل – من وجهة نظر ستيف – بعد كفاح شخصي منه طال زمن يقدر بالعشر سنين حيث كان من أهدافه في بداية مشروع المتجر احتواء كل أغنية تم إنتاجها سواء قديمة أو حديثة خاصة الشهيرة منها.

هل هي خطوة جيدة ؟! بالتأكيد

دعاية مبالغ فيها ؟!! ربما – على الأقل من وجهة نظر عربية -

هل هو يوم لا ينسى كما ذكرت آبل ؟!! نعم، لأنه يحمل آمال و ذكريات، آمال لم تتحقق .. و ذكريات صادمة أليمة !!

ملحوظة: الإعلان موجود على الصفحة الرئيسية في مواقع الدول التي أتيح فيها الشراء و غير ذلك الصفحة الرئيسية كما هي حتى لا يتهم أحد آبل بعدم مراعاتهم.

مواضيع مشابهة:


سلسلة دروس برمجة تطبيقات الآيفون (3) “مثال تطبيقي”

Posted: 20 Nov 2010 02:55 AM PST

1276627696_14277791302d16557a6fbo

سنتكلم عن درس تطبيقي تابع للدروس السابقة وخاصة الدرس الثالث ، في هذا الدرس سنعمل على إضافة class خاصة ونضع فيها مانريد بحيث نستطيع استخدامها لاحقًا مع تطبيقات الآيفون لكننا في البداية نطبقها في الـ command line tool حتى نتأكد من عدم وجود أي أخطاء فيها.

فكرة التطبيق هو وضع class تقوم بحساب عدد أضلع المضلع وحساب الزوايا بين المضلعات وإعطاء اسم المضلع؛ إن كان لديه ثلاثة أضلع فهو معين أو أربع فهو مربع وهكذا…

في البداية من xcode->create a new Xcode project->Mac OS X->Application->Command Line Tool

وكما نوهنا في الدرس التطبيقي السابق لا بد من التأكد بأن النوع هو Foundation.

بعد ذلك نختار الاسم وبالنسبة لي اخترت Lab3 ونعمل له حفظ ستظهر لنا هذه الشاشة مع ملف الـ Lab3.m .

ثم نذهب الآن إلى File->New File ->Mac OS X-> Cocoa->Objecitve-C class ونتأكد من أن هناك علامة على create header file ونسمي الملف PolygonShape

الآن كما أخذنا في الدرس الثالث عن تعريف المتغيرات بواسطة property  وكيف أنها توفر لي عناء وضع setter/getter methods وتوفر أيضا مواصفات أخرى للمتغير.

سنقوم الآن بالذهاب إلى ملف PolygonShape.h ونضيف إليه تعريف المتغيرات التالية:

int numberOfSides;// عدد الأضلع

int minimumNumberOfSides;// القيمة الأدنى لعدد الأضلع

int maximumNumberOfSides;//القيمة القصوى لعدد الأضلع

وأيضا نضيف تعاريف أخرى لكن مع خاصية الـ property بحيث يكون ملف الـ PolygonShape.h بهذا الشكل:

#import <Cocoa/Cocoa.h>

@interface PolygonShape : NSObject {

int numberOfSides;

int minimumNumberOfSides;

int maximumNumberOfSides;

}

//decalreing the properties

@property int numberOfSides;

@property int minimumNumberOfSides;

@property int maximumNumberOfSides;

@property (readonly) float angleInDegrees; // هنا أضفنا قيمة وتكون للقراءة فقط أي لا يعدل عليها فلا أستطيع أن أعمل لها

Setter

وتحسب الزاوية بالدرجة

@property (readonly) float angleInRadians;// هنا المتغير يحسب الزاوية بالراديان

@property (readonly) NSString *name;// هنا اسم المضلع بحسب عدد أضلعه

@end

وكما رأينا في الدرس الثالث أنه عندما أعرف متغير بالـ property فإنه في ملف .m نعمل له synthesized والتي تقوم مقام الـ setter/getter. ننتقل الآن إلى ملف الـPolygonShape.m ونعمل للمتغيرات synthesized:

@synthesize numberOfSides;

@synthesize minimumNumberOfSides;

@synthesize maximumNumberOfSides;

سنعمل على تعديل الـ setter  لكل من المتغيرات الثلاثة بحيث أن numberOfSides يجب أن يكون أقل من maximumNumberOfSides وأكثر من minimumNumberOfSides وأما بالنسبة للـ minimumNumberOfSides يجب أن تكون أعلى من أقل قيمة أريدها ولنفرض أنها 2 وأما maximumNumberOfSides فيجب أن تكون أقل أو تساوي أعلى قيمة أريدها ولنفرض أنها 12.

- (void)setNumberOfSides:(int)sides{ // الدالة التابعة للمتغير عدد أضلع المعين

if (sides<minimumNumberOfSides || sides>maximumNumberOfSides) {// تحديد القيم التي يجب أن تكون محصورة بينها

if(sides<minimumNumberOfSides){// في حال كانت أقل من أقل قيمة مفروضة فإنها تطبع رسالة بالخطأ

NSLog(@”Invalid number of sides: %d is less than the minimum number of %d allowed”,sides,minimumNumberOfSides);}

else {// في حال كانت أكبر من أعلى قيمة مفروضة أيضا تطبع رسالة خطأ

NSLog(@”Invalid number of sides: %d is more than the maximum number of %d allowed”, sides, maximumNumberOfSides);

} else {// في حال أن القيمة صحيحة ومحصورة بين العددين فنساوي القيمة المعطاة بقيمة عدد الأضلع

numberOfSides = sides;}

}

- (void)setMinimumNumberOfSides:(int)min{

if (min<2) {// في حالة أن القيمة أقل من 2

NSLog(@”Attempting to set too low”);// يطبع رسالة خطأ بأن القيمة قليلة جدا

} else {

minimumNumberOfSides = min;// في حالة أنها صحيحة فإننا نساوي أقل عدد بالقيمة المعطاة

}}

- (void)setMaximumNumberOfSides:(int)max{

if (max>12) {// في حالة أن القيمة أعلى من 12

NSLog(@”Attempting to set higher than min”);// طبع رسالة خطأ بأن القيمة عالية جدا

} else {

maximumNumberOfSides = max;// أما اذا كانت صحيحة فإننا نساوي أعلى قيمة بالقيمة المعطاة

}}

سنضيف إلى ملف PolygonShape.h دالة تعطي قيم ابتدائية للمتغيرات وهي:

- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;// بحيث أنها تأخذ عدد أضلاع المضلع وأقل قيمة وأعلى قيمة

وفي ملف الـ  PolygonShape.m نضيف التالي:

- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max {

if (self = [super init]) {

[self setMaximumNumberOfSides:max];

[self setMinimumNumberOfSides:min];

[self setNumberOfSides:sides];}

return self;

}

وكما نعلم أن self هو نفسه المقصود به this فعندما استخدم self أقصد فيه المتغير الموجود في نفس ال class. نلاحظ هنا أنا عملنا set لأعلى قيمة وأدنى قيمة قبل عمل ذلك لعدد الأضلع وذلك حتى تطبق الشرط الذي استخدمته بأن عدد الأضلع يجب أن يكون محدود بين أعلى قيمة وأدنى قيمة.

أيضا نستطيع الكتابة على الدالة الأساسية التابعة NSObject وهي init وإعطائها الكود الذي أريد لكن يجب في البداية تعريفها في ملف .h ثم التعديل عليها في ملف .m ففي ملف .h سنضيف التالي

- (id)init;

وفي ملف .m سنضيف

- (id)init {

return [self initWithNumberOfSides:5 minimumNumberOfSides:2 maximumNumberOfSides:12];

}

فهنا أعطيت أعلى قيمة 12 وأقل قيمة 2 وعدد الأضلع 5 كقيم افتراضية.

فإما أن أعمل قيم ابتدائية لأي object من PolygonShap class بواسطة initWithNumberOfSides  أو بواسطة init.

سنضيف الآن getter method لباقي المتغيرات

- (float)angleInDegrees {// هذه دالة تحسب قيمة زاويا المضلع بالدرجة وفق معادلة معينة

return (180 * (numberOfSides – 2) / numberOfSides);

}

- (float)angleInRadians {// هذه دالة تحسب قيمة زوايا المضلع بالراديان وفق معادلة معينة

return (M_PI * (numberOfSides – 2) / numberOfSides);

}

- (NSString *)name {// هنا أنشأنا لأسماء المضلعات قاموس بحيث بحسب عدد الأضلع سيكون مسمى المضلع

// وسبق استخدمنا القاموس في الدرس التطبيقي الثاني أرجو الرجوع إليه في حالة استيعاب الفكرة

NSDictionary *names = [NSDictionary dictionaryWithObjectsAndKeys:@"Triangle", [NSNumber numberWithInt:3],

@”Square”, [NSNumber numberWithInt:4],

@”Pentagon”, [NSNumber numberWithInt:5],

@”Hexagon”, [NSNumber numberWithInt:6],

@”Heptagon”, [NSNumber numberWithInt:7],

@”Octagon”, [NSNumber numberWithInt:8],

@”Nonagon”, [NSNumber numberWithInt:9],

@”Decagon”, [NSNumber numberWithInt:10],

@”Hendecagon”, [NSNumber numberWithInt:11],

@”Dodecagon”, [NSNumber numberWithInt:12], nil];

return [names objectForKey:[NSNumber numberWithInt:[self numberOfSides]]]; }

- (NSString *)description {// هذه الدالة ستعطيني وصف كامل للمضلع الذي أنشأته عدد أضلعه وزاويته واسمه

return [NSString stringWithFormat:@"Hello I am a %d-sided polygon (aka a %@) with angles of %.0f degrees (%f radians).", [self numberOfSides], [self name], [self angleInDegrees], [self angleInRadians]];

}

سيكون الملفين بشكل نهائي بهذا الشكل:

PolygonShape.h

#import <Cocoa/Cocoa.h>

@interface PolygonShape : NSObject {

int numberOfSides;

int minimumNumberOfSides;

int maximumNumberOfSides;

}

//decalreing the properties

@property int numberOfSides;

@property int minimumNumberOfSides;

@property int maximumNumberOfSides;

@property (readonly) float angleInDegrees;

@property (readonly) float angleInRadians;

@property (readonly) NSString *name;

- (id)init;

- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;

- (void)dealloc;

@end

PolygonShape.m

#import “PolygonShape.h”

@implementation PolygonShape

@synthesize numberOfSides;

@synthesize minimumNumberOfSides;

@synthesize maximumNumberOfSides;

- (void)dealloc {

NSLog(@”Deallocating”);

[super dealloc];

}

- (id)init {

return [self initWithNumberOfSides:5 minimumNumberOfSides:2 maximumNumberOfSides:12];

}

- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max {

if (self = [super init]) {

[self setMaximumNumberOfSides:max];

[self setMinimumNumberOfSides:min];

[self setNumberOfSides:sides];

}

return self;

}

- (void)setNumberOfSides:(int)sides{

if (sides<minimumNumberOfSides || sides>maximumNumberOfSides) {

if(sides<minimumNumberOfSides){

NSLog(@”Invalid number of sides: %d is less than the minimum number of %d allowed”,sides,minimumNumberOfSides);

} else {

NSLog(@”Invalid number of sides: %d is more than the maximum number of %d allowed”, sides, maximumNumberOfSides);

}} else {

numberOfSides = sides;

}}

- (void)setMinimumNumberOfSides:(int)min{

if (min<2) {

NSLog(@”Attempting to set too low”);

} else {

minimumNumberOfSides = min;

}}

- (void)setMaximumNumberOfSides:(int)max{

if (max>12) {

NSLog(@”Attempting to set higher than min”);

} else {

maximumNumberOfSides = max;}}

- (float)angleInDegrees {

return (180 * (numberOfSides – 2) / numberOfSides);

}

- (float)angleInRadians {

return (M_PI * (numberOfSides – 2) / numberOfSides);

}

- (NSString *)name {

NSDictionary *names = [NSDictionary dictionaryWithObjectsAndKeys:@"Triangle", [NSNumber numberWithInt:3],

@”Square”, [NSNumber numberWithInt:4],

@”Pentagon”, [NSNumber numberWithInt:5],

@”Hexagon”, [NSNumber numberWithInt:6],

@”Heptagon”, [NSNumber numberWithInt:7],

@”Octagon”, [NSNumber numberWithInt:8],

@”Nonagon”, [NSNumber numberWithInt:9],

@”Decagon”, [NSNumber numberWithInt:10],

@”Hendecagon”, [NSNumber numberWithInt:11],

@”Dodecagon”, [NSNumber numberWithInt:12], nil];

return [names objectForKey:[NSNumber numberWithInt:[self numberOfSides]]];

}

- (NSString *)description {

return [NSString stringWithFormat:@"Hello I am a %d-sided polygon (aka a %@) with angles of %.0f degrees (%f radians).", [self numberOfSides], [self name], [self angleInDegrees], [self angleInRadians]];

}

@end

ثم بعد ذلك نعمل build and run ويجب أن لا يكون هناك أي خطأ.

ثم بعد ذلك ننتقل إلى ملف Lab3.m  وفي الـ main   سنضيف الدالة التالية PrintPolygonInfo   :

int main (int argc, const char * argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

PrintPolygonInfo();  // insert code here…

[pool release];

return 0;

}

ولا ننسى في رأس ملف Lab3.m أن ننادي PolygonShape.h :

#import “PolygonShap.h”;

هذه الدالة سنعمل على إنشائها قبل دالة الـ main بحيث سنستخدم الدوال الموجودة في ملف PolygonShape.h وستكون الدالة كالتالي:

void PrintPolygonInfo(){

NSLog(@”===Print Polygon Info====”);//هذا السطر للطباعة فقط

NSMutableArray *polygons = [[NSMutableArray alloc] init];

هنا أنشأنا Array وتكون من نوع Mutable الذي يمكن التعديل عليه بسهولة بدون حذف وإنشاء//

PolygonShape *poly1 = [[PolygonShape alloc] initWithNumberOfSides:4 minimumNumberOfSides:3 maximumNumberOfSides:7];

هنا أنشأنا متغير من نوع PolygonShape ونادينا له الدالة التي تعمل قيمة ابتدائية لكل من عدد side وأكبر عدد وأقل عدد//

PolygonShape *poly2 = [[PolygonShape alloc] initWithNumberOfSides:6 minimumNumberOfSides:5 maximumNumberOfSides:9];

تم تعريف شكل آخر بنفس الطريقة//

PolygonShape *poly3 = [[PolygonShape alloc] init];

[poly3 setNumberOfSides:12];

تم تعريف شكل ثالث لكن نادينا دالة أخرى تعمل قيم ابتدائية واكتفينا فقط بقيمة عدد الـ side //

poly3.minimumNumberOfSides = 9;

poly3.maximumNumberOfSides = 12;

بعد ذلك نادينا دوال لأعلى قيمة وأقل قيمة لعدد side //

[polygons addObject:poly1];

[polygons addObject:poly2];

[polygons addObject:poly3];

هنا أضفنا جميع الأشكال إلى Array //

for (id poly in polygons) {

هنا أضفنا For loop تقوم بإظهار جميع الوصوف للأشكال الموجودة في polygons array //

سيذكر عدد الـside والزاوية بالدرجة والراديان كما هو موضح في دالة الـ description //

NSLog(@”%@”,[poly description]);

}

for (id poly in polygons) {

هنا سنعمل على إعطاء عدد الـ side 10 لكل الأشكال ونلاحظ أنه سيظهر لنا رسالة خطأ في الشكلين الأولين //

وذلك لأن عدد الـ side أكبر من أكبر قيمة للشكل أما في الشكل الأخير فإنه يقبله//

[poly setNumberOfSides:10];

}

for (id poly in polygons) {

هنا سنعمل release لجميع الأشكال التي أنشأناها حتى لايكون هناك مشاكل مع الذاكرة//

[poly release];

}

هنا نعمل release للـ Array التي أنشأناها أيضا//

[polygons release];

}

أرجو الاحتفاظ بهذا المثال التطبيقي لأننا سنرجع إليه في الأمثلة التطبيقية القادمة إن شاء الله …

شكرًا لتشجيعكم ودعمكم المعنوي..

دمتم بود :)

مواضيع مشابهة: