├── .gitmodules
├── LTUpdate Demo
├── LTUpdate Demo
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── Default.png
│ ├── Default@2x.png
│ ├── Default-568h@2x.png
│ ├── LTAppDelegate.h
│ ├── main.m
│ ├── LTUpdate Demo-Prefix.pch
│ ├── LTUpdate Demo-Info.plist
│ └── LTAppDelegate.m
├── LTUpdate DemoTests
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── LTUpdate_DemoTests.h
│ ├── LTUpdate DemoTests-Info.plist
│ └── LTUpdate_DemoTests.m
├── Screenshot_APP_STORE_ID.png
├── Screenshot_Multilingual.jpg
├── Screenshot_Notification.png
└── LTUpdate Demo.xcodeproj
│ ├── project.xcworkspace
│ └── contents.xcworkspacedata
│ └── project.pbxproj
├── LTUpdate
├── LTI18N
│ ├── zh-Hans.lproj
│ │ └── LTUpdate.strings
│ ├── zh-Hant.lproj
│ │ └── LTUpdate.strings
│ ├── zh-Hant-TW.lproj
│ │ └── LTUpdate.strings
│ ├── ja.lproj
│ │ └── LTUpdate.strings
│ ├── ko.lproj
│ │ └── LTUpdate.strings
│ ├── ar.lproj
│ │ └── LTUpdate.strings
│ ├── da.lproj
│ │ └── LTUpdate.strings
│ ├── en.lproj
│ │ └── LTUpdate.strings
│ ├── ro.lproj
│ │ └── LTUpdate.strings
│ ├── ru.lproj
│ │ └── LTUpdate.strings
│ ├── es.lproj
│ │ └── LTUpdate.strings
│ ├── sv.lproj
│ │ └── LTUpdate.strings
│ ├── nl.lproj
│ │ └── LTUpdate.strings
│ ├── pt-BR.lproj
│ │ └── LTUpdate.strings
│ ├── th.lproj
│ │ └── LTUpdate.strings
│ ├── uk.lproj
│ │ └── LTUpdate.strings
│ ├── pl.lproj
│ │ └── LTUpdate.strings
│ ├── sk.lproj
│ │ └── LTUpdate.strings
│ ├── sl.lproj
│ │ └── LTUpdate.strings
│ ├── cs.lproj
│ │ └── LTUpdate.strings
│ ├── pt-PT.lproj
│ │ └── LTUpdate.strings
│ ├── tr.lproj
│ │ └── LTUpdate.strings
│ ├── it.lproj
│ │ └── LTUpdate.strings
│ ├── fr.lproj
│ │ └── LTUpdate.strings
│ └── de.lproj
│ │ └── LTUpdate.strings
├── LTUpdate.h
└── LTUpdate.m
├── LICENSE
└── README.md
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "JSONKit"]
2 | path = JSONKit
3 | url = git@github.com:johnezang/JSONKit.git
4 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate DemoTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyric/LTUpdate/master/LTUpdate Demo/LTUpdate Demo/Default.png
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyric/LTUpdate/master/LTUpdate Demo/LTUpdate Demo/Default@2x.png
--------------------------------------------------------------------------------
/LTUpdate Demo/Screenshot_APP_STORE_ID.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyric/LTUpdate/master/LTUpdate Demo/Screenshot_APP_STORE_ID.png
--------------------------------------------------------------------------------
/LTUpdate Demo/Screenshot_Multilingual.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyric/LTUpdate/master/LTUpdate Demo/Screenshot_Multilingual.jpg
--------------------------------------------------------------------------------
/LTUpdate Demo/Screenshot_Notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyric/LTUpdate/master/LTUpdate Demo/Screenshot_Notification.png
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyric/LTUpdate/master/LTUpdate Demo/LTUpdate Demo/Default-568h@2x.png
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate DemoTests/LTUpdate_DemoTests.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTUpdate_DemoTests.h
3 | // LTUpdate DemoTests
4 | //
5 | // Created by Lex on 18/2/13.
6 | // Copyright (c) 2013 Lex Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTUpdate_DemoTests : SenTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/zh-Hans.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "新的版本已经提供下载了!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ 已经提供下载。您现在的版本是 %3$@。您要现在下载(%4$@)它吗?";
4 |
5 | "Update" = "更新";
6 |
7 | "Skip This Version" = "跳过这个版本";
8 |
9 | "Remind Me Later" = "以后再提醒我";
10 |
11 | "Release Notes" = "更新信息";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/zh-Hant.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "新的版本已經提供下載了!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ 已經提供下載。您現在的版本是 %3$@。您要現在下載(%4$@)它嗎?";
4 |
5 | "Update" = "更新";
6 |
7 | "Skip This Version" = "跳過這個版本";
8 |
9 | "Remind Me Later" = "以後再提醒我";
10 |
11 | "Release Notes" = "更新信息";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/zh-Hant-TW.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "新的版本已經提供下載了!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ 已經提供下載。您現在的版本是 %3$@。您要現在下載(%4$@)它嗎?";
4 |
5 | "Update" = "更新";
6 |
7 | "Skip This Version" = "跳過這個版本";
8 |
9 | "Remind Me Later" = "以後再提醒我";
10 |
11 | "Release Notes" = "更新資訊";
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/LTAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTAppDelegate.h
3 | // LTUpdate Demo
4 | //
5 | // Created by Lex on 18/2/13.
6 | // Copyright (c) 2013 Lex Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LTAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/ja.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "新しいバージョンが入手できます!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ が入手できます(使用中のバージョンは %3$@ です)。今すぐダウンロードしますか(%4$@)?";
4 |
5 | "Update" = "アップデート";
6 |
7 | "Skip This Version" = "このバージョンはスキップ";
8 |
9 | "Remind Me Later" = "後で通知";
10 |
11 | "Release Notes" = "リリースノート";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/ko.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "새 버전을 사용할 수 있습니다!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ 사용할 수 있습니다. 당신은 %3$@ 수 있습니다. 당신은 지금 (%4$@)를 다운로드 하시겠습니까?";
4 |
5 | "Update" = "새롭게하다";
6 |
7 | "Skip This Version" = "이 버전 건너뛰기";
8 |
9 | "Remind Me Later" = "나중에";
10 |
11 | "Release Notes" = "배포 정보";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/ar.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "يتوفر إصدار جديد من تطبيق!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ متوفر الآن. لديك %3$@. ترغب تحميل (%4@) الآن؟";
4 |
5 | "Update" = "Update";
6 |
7 | "Skip This Version" = "تخطي هذا الإصدار";
8 |
9 | "Remind Me Later" = "تذكيري لاحقًا";
10 |
11 | "Release Notes" = "معلومات عن الإصدار:";
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // LTUpdate Demo
4 | //
5 | // Created by Lex on 18/2/13.
6 | // Copyright (c) 2013 Lex Tang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "LTAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([LTAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/da.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "En ny version er tilgængelig!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ er nu tilgængelig - du har %3$@. Vil du hente den nu(%4$@)?";
4 |
5 | "Update" = "Opdatering";
6 |
7 | "Skip This Version" = "Skip denne version";
8 |
9 | "Remind Me Later" = "Påmind mig senere";
10 |
11 | "Release Notes" = "Udgivelsesnoter";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/en.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "A new version is available!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ is now available. You have %3$@. Would you like to download(%4$@) it now?";
4 |
5 | "Update" = "Update";
6 |
7 | "Skip This Version" = "Skip This Version";
8 |
9 | "Remind Me Later" = "Remind Me Later";
10 |
11 | "Release Notes" = "Release Notes";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/ro.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "O nouă versiune este disponibilă!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ este disponibilă—-tu ai %3$@. Doriți să o descărcați(%4$@) acum?";
4 |
5 | "Update" = "Actualizare";
6 |
7 | "Skip This Version" = "Sari peste";
8 |
9 | "Remind Me Later" = "Amintește-mi mai târziu";
10 |
11 | "Release Notes" = "Note de ediție";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/ru.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Имеется новая версия!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ теперь доступен – вы имеете %3$@. Хотите загрузить (%4$@) его сейчас?";
4 |
5 | "Update" = "обновление";
6 |
7 | "Skip This Version" = "Пропустить эту версию";
8 |
9 | "Remind Me Later" = "Напоминать позже";
10 |
11 | "Release Notes" = "Заметки о выпуске";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/es.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "¡Hay una nueva versión!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ está disponible (usted tiene la %3$@). ¿Desea descargarla ahora(%4$@)?";
4 |
5 | "Update" = "Instalar";
6 |
7 | "Skip This Version" = "No instalar esta versión";
8 |
9 | "Remind Me Later" = "Recordármelo";
10 |
11 | "Release Notes" = "Notas de la versión";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/sv.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "En ny version finns tillgänglig!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ är nu tillgänglig—du har %3$@. Vill du ladda(%4$@) ned nu?";
4 |
5 | "Update" = "Uppdate";
6 |
7 | "Skip This Version" = "Hoppa över denna version";
8 |
9 | "Remind Me Later" = "Påminn mig senare";
10 |
11 | "Release Notes" = "Versionsinformation";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/nl.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Een nieuwe versie is beschikbaar!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ is nu beschikbaar—u heeft %3$@. Wilt u het nu downloaden(%4$@)?";
4 |
5 | "Update" = "Update";
6 |
7 | "Skip This Version" = "Sla deze versie over";
8 |
9 | "Remind Me Later" = "Herinner mij er later aan";
10 |
11 | "Release Notes" = "Versiegegevens";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/pt-BR.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Uma nova versão está disponível!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ está disponível--sua versão é %3$@. Gostaria de baixá-lo agora(%4$@)?";
4 |
5 | "Update" = "Atualização";
6 |
7 | "Skip This Version" = "Pular Esta Versão";
8 |
9 | "Remind Me Later" = "Mais Tarde";
10 |
11 | "Release Notes" = "Sobre a atualização";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/th.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "เวอร์ชั่นใหม่ของพร้อมสำหรับการติดตั้งแล้ว";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ พร้อมให้ดาวน์โหลดแล้ว (คุณมีเวอร์ชั่น %3$@) ดาวน์โหลด(%4$@)หรือไม่";
4 |
5 | "Update" = "อัพเดท";
6 |
7 | "Skip This Version" = "ข้ามเวอร์ชั่นนี้";
8 |
9 | "Remind Me Later" = "เตือนในภายหลัง";
10 |
11 | "Release Notes" = "หมายเหตุการเผยแพร่";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/uk.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Нова версія готова до встановлення!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ доступна – ви маєте %3$@. Бажаєте завантажити(%4$@) її зараз?";
4 |
5 | "Update" = "Oновлення";
6 |
7 | "Skip This Version" = "Пропустити цю версію";
8 |
9 | "Remind Me Later" = "Нагадати пізніше";
10 |
11 | "Release Notes" = "Примітки про нову версію";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/pl.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Dostępna jest nowa wersja %@!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ jest już dostępny (aktualnie posiadasz %3$@). Chciałbyś go teraz pobrać(%4$@)?";
4 |
5 | "Update" = "Zainstaluj";
6 |
7 | "Skip This Version" = "Pomiń tę wersję";
8 |
9 | "Remind Me Later" = "Przypomnij później";
10 |
11 | "Release Notes" = "Szczegóły wydania";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/sk.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Nová verzia je k dispozícii!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ je teraz k dispozícii. Máte %3$@. Chceli by ste na stiahnutie (%4$@) to teraz?";
4 |
5 | "Update" = "Update";
6 |
7 | "Skip This Version" = "Vynechať túto verziu";
8 |
9 | "Remind Me Later" = "Pripomenúť neskôr";
10 |
11 | "Release Notes" = "Poznámky k vydaniu";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/sl.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Na voljo je nova verzija programa!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "Na voljo je %1$@ %2$@ — vi imate %3$@. Ga želite prenesti s spleta sedaj(%4$@)?";
4 |
5 | "Update" = "Posodabljanje";
6 |
7 | "Skip This Version" = "Preskoči to verzijo";
8 |
9 | "Remind Me Later" = "Spomni me kasneje";
10 |
11 | "Release Notes" = "Opombe ob izdaji";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/cs.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Je dostupná nová verze aplikace!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "Je k dispozici %1$@ %2$@ - máte %3$@. Přejete si nyní zkopírovat aktualizaci (%4$@)?";
4 |
5 | "Update" = "Aktualizaci";
6 |
7 | "Skip This Version" = "Přeskočit tuto verzi";
8 |
9 | "Remind Me Later" = "Připomenout později";
10 |
11 | "Release Notes" = "Poznámky k vydání";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/pt-PT.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Uma nova versão está dísponível!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "O %1$@ %2$@ está agora disponível e tem a versão %3$@. Gostaria de o transferir agora(%4$@)?";
4 |
5 | "Update" = "Actualização";
6 |
7 | "Skip This Version" = "Saltar esta versão";
8 |
9 | "Remind Me Later" = "Lembrar mais tarde";
10 |
11 | "Release Notes" = "Notas de lançamento";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/tr.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Uygulamasının yeni bir sürümü yüklemeye hazır!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ çıktı (Kullandığınız Sürüm: %3$@). Şimdi yeni sürümü indirmek(%4$@) ister misiniz?";
4 |
5 | "Update" = "Güncellemeyi";
6 |
7 | "Skip This Version" = "Bu sürümü geç";
8 |
9 | "Remind Me Later" = "Tekrar Hatırlat";
10 |
11 | "Release Notes" = "Sürüm Hakkında";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/it.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "E’ disponibile una nuova versione!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ è disponbile; disponi della versione %3$@. Desideri eseguire l’aggiornamento ora(%4$@)?";
4 |
5 | "Update" = "Installa";
6 |
7 | "Skip This Version" = "Ignora questa versione";
8 |
9 | "Remind Me Later" = "Ricordamelo più tardi";
10 |
11 | "Release Notes" = "Note di rilascio";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/fr.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Une nouvelle version est disponible !";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ est disponible ; vous utilisez la version %3$@. Voulez-vous le télécharger(%4$@) maintenant ?";
4 |
5 | "Update" = "Mise à jour";
6 |
7 | "Skip This Version" = "Ignorer cette version";
8 |
9 | "Remind Me Later" = "Pas maintenant";
10 |
11 | "Release Notes" = "Notes de version";
--------------------------------------------------------------------------------
/LTUpdate/LTI18N/de.lproj/LTUpdate.strings:
--------------------------------------------------------------------------------
1 | "A new version is available!" = "Eine neue Version ist verfügbar!";
2 |
3 | "%@ %@ is now available. You have %@. Would you like to download(%@) it now?" = "%1$@ %2$@ ist verfügbar (Sie verwenden Version %3$@). Möchten Sie die neue Version jetzt herunterladen(%4$@)?";
4 |
5 | "Update" = "Aktualisierung";
6 |
7 | "Skip This Version" = "Diese Version überspringen";
8 |
9 | "Remind Me Later" = "Später erinnern";
10 |
11 | "Release Notes" = "Versionshinweise";
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/LTUpdate Demo-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'LTUpdate Demo' target in the 'LTUpdate Demo' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_3_0
8 | #warning "This project uses features only available in iOS SDK 3.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 |
15 | #if (defined __IPHONE_OS_VERSION_MIN_REQUIRED && \
16 | __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0)
17 | #import "JSONKit.h"
18 | #endif
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate DemoTests/LTUpdate DemoTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.lextang.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 0.1
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2013 LexTang.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/LTUpdate Demo-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APP_STORE_ID
6 | 361309726
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | La vie
11 | CFBundleExecutable
12 | ${EXECUTABLE_NAME}
13 | CFBundleIdentifier
14 | com.lextang.${PRODUCT_NAME:rfc1034identifier}
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | ${PRODUCT_NAME}
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.7.0
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 1
27 | LSRequiresIPhoneOS
28 |
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate DemoTests/LTUpdate_DemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTUpdate_DemoTests.m
3 | // LTUpdate DemoTests
4 | //
5 | // Created by Lex on 18/2/13.
6 | // Copyright (c) 2013 Lex Tang. All rights reserved.
7 | //
8 |
9 | #import "LTUpdate_DemoTests.h"
10 | #import "LTUpdate.h"
11 |
12 | @implementation LTUpdate_DemoTests
13 |
14 | - (void)setUp {
15 | [super setUp];
16 | STAssertFalse([kAppVersion() compare:@"0.0" options:NSNumericSearch] == NSOrderedSame,
17 | @"App version MUST be greater then zero.");
18 |
19 | STAssertNotNil(kAppName(), @"App display name should not be nil.");
20 | }
21 |
22 | - (void)tearDown {
23 | // Tear-down code here.
24 |
25 | [super tearDown];
26 | }
27 |
28 | - (void)testAppStoreID {
29 | long appStoreID = [[LTUpdate shared] appStoreID];
30 | STAssertTrue(appStoreID - 361309726 == 0, @"AppStoreID must be fill in -Info.plist");
31 | }
32 |
33 | - (void)testVersionSkip {
34 | [[LTUpdate shared] skipVersion:@"0.1"];
35 | STAssertTrue([[LTUpdate shared] isVersionSkipped:@"0.1"], @"Version 0.1 must be skipped.");
36 | [[LTUpdate shared] clearSkippedVersion];
37 | STAssertFalse([[LTUpdate shared] isVersionSkipped:@"0.1"], @"SkippedVersion must be cleared.");
38 | }
39 |
40 | - (void)testUpdateVersion {
41 | dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
42 |
43 | [[LTUpdate shared] update:LTUpdateHourly
44 | complete:^(BOOL isNewVersionAvailable, LTUpdateVersionDetails *versionDetails) {
45 |
46 | if (isNewVersionAvailable) {
47 |
48 | STAssertTrue([versionDetails.version compare:@"0.0" options:NSNumericSearch] == NSOrderedDescending,
49 | @"App Store version should be greater than zero.");
50 | STAssertNotNil(versionDetails.releaseNotes, @"Release notes should not be nil.");
51 | STAssertTrue(versionDetails.fileSizeBytes > 0, @"File size should be greater than zero.");
52 |
53 | NSString *readableFileSize = humanReadableFileSize(versionDetails.fileSizeBytes);
54 | STAssertTrue(readableFileSize && readableFileSize.length > 2, @"Human readable file size should not be empty.");
55 | STAssertTrue(versionDetails.releaseDate.timeIntervalSince1970 > 0, @"Release date should be valid.");
56 |
57 | } else {
58 |
59 | STAssertNil(versionDetails, @"Version details must be nil while there is no new version.");
60 |
61 | }
62 |
63 | dispatch_semaphore_signal(semaphore);
64 | }];
65 |
66 | while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
67 | [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
68 | beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
69 | dispatch_release(semaphore);
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo/LTAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTAppDelegate.m
3 | // LTUpdate Demo
4 | //
5 | // Created by Lex on 18/2/13.
6 | // Copyright (c) 2013 Lex Tang. All rights reserved.
7 | //
8 |
9 | #import "LTAppDelegate.h"
10 | #import "LTUpdate.h"
11 | //#import "MBAlertView.h"
12 |
13 | @implementation LTAppDelegate
14 |
15 | - (void)dealloc
16 | {
17 | [_window release];
18 | [super dealloc];
19 | }
20 |
21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
22 | {
23 | self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
24 | UIViewController *rootViewController = [[UIViewController alloc] init];
25 | rootViewController.view.backgroundColor = [UIColor colorWithWhite:0.298 alpha:1.000];
26 | self.window.rootViewController = rootViewController;
27 | [self.window makeKeyAndVisible];
28 | return YES;
29 | }
30 |
31 | - (void)applicationDidBecomeActive:(UIApplication *)application
32 | {
33 | // [[LTUpdate shared] updateAndPush:LTUpdateDaily]; return;
34 |
35 | [[LTUpdate shared] update:LTUpdateHourly
36 | complete:^(BOOL isNewVersionAvailable, LTUpdateVersionDetails *versionDetails) {
37 |
38 | //*// [TIP] Remove the first slash to toggle block comments if you'd like to use MBAlertView.
39 | if (isNewVersionAvailable) {
40 | NSLog(@"New version %@ released on %@.", versionDetails.version, versionDetails.releaseDate);
41 | NSLog(@"The app is about %@", humanReadableFileSize(versionDetails.fileSizeBytes));
42 | NSLog(@"Release notes:\n%@", versionDetails.releaseNotes);
43 | [[LTUpdate shared] alertLatestVersion:LTUpdateOption | LTUpdateSkip];
44 | } else {
45 | NSLog(@"You App is up to date.");
46 | }
47 | /*/
48 | if (isNewVersionAvailable) {
49 | NSString *text = [NSString stringWithFormat:@"%@\n\n%@", LTI18N(@"A new version is available!"), versionDetails.releaseNotes];
50 | MBAlertView *alertView = [MBAlertView alertWithBody:text
51 | cancelTitle:LTI18N(@"Remind Me Later") cancelBlock:nil];
52 | [alertView addButtonWithText:LTI18N(@"Update") type:MBAlertViewItemTypeDefault block:^{
53 | [[LTUpdate shared] openAppStore];
54 | }];
55 | alertView.bodyFont = [UIFont systemFontOfSize:11];
56 | [alertView addToDisplayQueue];
57 | } else {
58 | NSLog(@"You App is up to date.");
59 | }
60 | //*/
61 | }];
62 | }
63 |
64 | - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
65 | {
66 | // [[LTUpdate shared] reduceNotification:notification then:LTUpdateNotifyThenAlert];
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/LTUpdate/LTUpdate.h:
--------------------------------------------------------------------------------
1 | //
2 | // LTUpdate.h
3 | // LTUpdate
4 | //
5 | // Created by Lex Tang on 18/2/13.
6 | //
7 | // The MIT License (MIT)
8 | // Copyright © 2013 Lex Tang, http://LexTang.com
9 | //
10 | // Permission is hereby granted, free of charge, to any person obtaining a copy
11 | // of this software and associated documentation files (the “Software”), to deal
12 | // in the Software without restriction, including without limitation the rights
13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | // copies of the Software, and to permit persons to whom the Software is
15 | // furnished to do so, subject to the following conditions:
16 | //
17 | // The above copyright notice and this permission notice shall be included in
18 | // all copies or substantial portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 | // THE SOFTWARE.
27 | //
28 |
29 | #import
30 | #import
31 |
32 | #ifndef lt_retain
33 | #if __has_feature(objc_arc)
34 | #define lt_retain self
35 | #define lt_dealloc self
36 | #define release self
37 | #define autorelease self
38 | #else
39 | #define lt_retain retain
40 | #define lt_dealloc dealloc
41 | #define __bridge
42 | #endif
43 | #endif
44 |
45 | #if (!__has_feature(objc_arc)) || \
46 | (defined __IPHONE_OS_VERSION_MIN_REQUIRED && \
47 | __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0)
48 | #undef weak
49 | #define weak unsafe_unretained
50 | #undef __weak
51 | #define __weak __unsafe_unretained
52 | #endif
53 |
54 |
55 | static NSString *kAppVersion() {
56 | static NSString *appVersion;
57 | static dispatch_once_t versionToken;
58 | dispatch_once(&versionToken, ^{
59 | appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
60 | });
61 | return appVersion;
62 | }
63 |
64 | static NSString *kAppName() {
65 | static NSString *appName;
66 | static dispatch_once_t nameToken;
67 | dispatch_once(&nameToken, ^{
68 | appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
69 | });
70 | return appName;
71 | }
72 |
73 | static NSString *humanReadableFileSize(unsigned long long int size) {
74 | NSString *sizeTypeW = @"bytes";
75 | float working = 0;
76 |
77 | if (size < 1) {
78 | return @"0KB";
79 | } else {
80 | if (size > 1024) {
81 | working = size / 1024.;
82 | sizeTypeW = @"KB";
83 | }
84 | if (working > 1024) {
85 | working = working / 1024.;
86 | sizeTypeW = @"MB";
87 | }
88 | }
89 | return [NSString stringWithFormat:@"%.2f%@", working, sizeTypeW];
90 | }
91 |
92 | static NSString *LTI18N(NSString *key) {
93 | NSString *localizedString = NSLocalizedStringFromTable(key, @"LTUpdate", nil);
94 | return localizedString ? localizedString : @"";
95 | }
96 |
97 |
98 | @interface LTUpdateVersionDetails : NSObject
99 |
100 | @property(nonatomic, strong) NSString *version;
101 | @property(nonatomic, strong) NSString *releaseNotes;
102 | @property(nonatomic, strong) NSDate *releaseDate;
103 | @property(nonatomic, assign) long long fileSizeBytes;
104 |
105 | @end
106 |
107 |
108 | typedef NS_ENUM(uint, LTUpdateOptions)
109 | {
110 | LTUpdateOption,
111 | LTUpdateForce,
112 | LTUpdateSkip
113 | };
114 |
115 | typedef NS_ENUM(uint, LTUpdateNotifyActions)
116 | {
117 | LTUpdateNotifyOpenAppStore,
118 | LTUpdateNotifyThenAlert,
119 | LTUpdateNotifyDoNothing
120 | };
121 |
122 | typedef NS_ENUM(uint, LTUpdatePeroid)
123 | {
124 | LTUpdateHourly,
125 | LTUpdateDaily,
126 | LTUpdateWeekly,
127 | LTUpdateMonthly
128 | };
129 |
130 | #ifndef LTUpdateBlocks
131 | #define LTUpdateBlocks
132 | typedef void(^LTUpdateCallback)(BOOL isNewVersionAvailable, LTUpdateVersionDetails *versionDetails);
133 | #endif
134 |
135 |
136 | @interface LTUpdate : NSObject
137 |
138 | @property(nonatomic, strong) LTUpdateVersionDetails *latestVersion;
139 | @property(nonatomic, assign, readonly) long appStoreID;
140 | @property(nonatomic, strong) LTUpdateCallback completionBlock;
141 |
142 | + (id)shared;
143 |
144 | - (void)__attribute__((unused)) update;
145 | - (void)__attribute__((unused)) update:(LTUpdateCallback)callback;
146 | - (void)update:(LTUpdatePeroid)peroid complete:(LTUpdateCallback)callback;
147 |
148 | - (BOOL)isVersionSkipped:(NSString *)version;
149 | - (void)skipVersion:(NSString *)version;
150 | - (void)clearSkippedVersion;
151 |
152 | - (void)__attribute__((unused)) alertLatestVersion:(LTUpdateOptions)alertOptions;
153 |
154 | - (void)__attribute__((unused)) updateAndPush;
155 | - (void)updateAndPush:(LTUpdatePeroid)peroid;
156 | - (void)__attribute__((unused)) pushLatestVersion;
157 | - (void)pushLatestVersion:(UILocalNotification*)localNotification;
158 | - (void)__attribute__((unused)) reduceNotification:(UILocalNotification*)notification;
159 | - (void)reduceNotification:(UILocalNotification*)notification then:(LTUpdateNotifyActions)action;
160 |
161 | - (void)openAppStore;
162 |
163 | @end
164 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LTUpdate
2 | LeT's Update to the new version available in the AppStore!
3 |
4 | [使用方法-简体中文](https://github.com/lexrus/LTUpdate/wiki/LTUpdate-使用方法)
5 |
6 | 
7 |
8 | ## Features
9 | * Local Notifications — from 0.0.2.
10 | * Customizable callback. You can prompt the new version with your favorite view class.
11 | * Multilingual. 25 languages included in version 0.0.1.
12 | * Update period control. Daily/Weekly/Monthly
13 | * “Skip This Version”
14 | * Version details (release date, file size in bytes, release notes...)
15 | * ARC/MRC compatible
16 | * Block based interfaces
17 | * GCD
18 |
19 | ## Requirements
20 | LTUpdate requires iOS 4.3 or newer.
21 |
22 | It's compatible with both ARC and MRC. But MRC mode is not well tested yet.
23 |
24 | [JSONKit](https://github.com/johnezang/JSONKit) is required while you are building for iOS 4.3.
25 |
26 |
27 | ## Usage
28 |
29 | ### DnD or pod install
30 | - Download the zip file and unzip it. Drag & drop LTUpdate/LTUpdate folder to your project.
31 | - But I prefer [CocoaPods](https://github.com/CocoaPods/CocoaPods): ```pod 'LTUpdate', '~>0.0.2'```
32 |
33 | ### Define the App ID
34 | - Add a NSNumber field to {{YourProjectName}}-Info.plist with key “APP_STORE_ID” and your App ID as value:
35 | 
36 |
37 | ### Import the header
38 | - After that, add ```#import "LTUpdate.h"``` to AppDelegate.m or {{YourProjectName}}-Prefix.pch.
39 |
40 | ### Prompt with UIAlertView
41 | - Invoke the update method in applicationDidBecomeActive: ```[[LTUpdate shared] update];```
42 | LTUpdate will check new verison from iTunes API. And prompt the user to update if there is a new version available.
43 |
44 | ### Prompt with Notification
45 | Users may be disturbed by UIAlertView while they supposed to use the app. Some of them installed your app but never open it till the new version has been promoted. Notifications is a better choice. Here is the simple way:
46 |
47 | ```
48 | - (void)applicationDidBecomeActive:(UIApplication *)application
49 | {
50 | [[LTUpdate shared] updateAndPush:LTUpdateDaily];
51 | }
52 |
53 | - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
54 | {
55 | [[LTUpdate shared] reduceNotification:notification then:LTUpdateNotifyThenAlert];
56 | }
57 | ```
58 | While your app become inactived, it would send a notification to notify the user to update.
59 |
60 | 
61 |
62 | If the user tap/swiped this notification, the action would be invoked. In this case, the app will show a alert to make confirm of update. Or it’s quite nifty to open AppStore directly with
63 | ```[[LTUpdate shared] reduceNotification:notification];```
64 |
65 | ### Customize
66 | If you need more control:
67 |
68 | ```
69 | [[LTUpdate shared] update:LTUpdateDaily
70 | complete:^(BOOL isNewVersionAvailable, LTUpdateVersionDetails *versionDetails) {
71 |
72 | if (isNewVersionAvailable) {
73 | NSLog(@"New version %@ published on %@.", versionDetails.version, versionDetails.releaseDate);
74 | NSLog(@"The app is about %@", humanReadableFileSize(versionDetails.fileSizeBytes));
75 | NSLog(@"Release notes:\n%@", versionDetails.releaseNotes);
76 | // Your alert view here
77 | [[LTUpdate shared] alertLatestVersion:LTUpdateOption | LTUpdateSkip];
78 | } else {
79 | NSLog(@"You App is up to date.");
80 | }
81 |
82 | }];
83 | ```
84 |
85 | Outputs:
86 |
87 | ```
88 | > New version 1.7.1 published on 2010-04-01 08:36:57 +0000.
89 | > The app is about 245.31MB
90 | > Release notes:
91 | In this release Pages for iOS is updated for improved compatibility with Microsoft Word and Pages for Mac.
92 | ...
93 | Pages 1.7.1 resolves issues related to Accessibility settings.
94 | ```
95 |
96 | A customized example shows you how to replace the alert view with other open source alternatives(MBAlertView for example):
97 |
98 | ```
99 | NSString *text = [NSString stringWithFormat:@"%@\n\n%@", LTI18N(@"A new version is available!"), versionDetails.releaseNotes];
100 | MBAlertView *alertView = [MBAlertView alertWithBody:text
101 | cancelTitle:LTI18N(@"Remind Me Later") cancelBlock:nil];
102 | [alertView addButtonWithText:LTI18N(@"Update") type:MBAlertViewItemTypeDefault block:^{
103 | [[LTUpdate shared] openAppStore];
104 | }];
105 | alertView.bodyFont = [UIFont systemFontOfSize:11];
106 | [alertView addToDisplayQueue];
107 | ```
108 |
109 | ### Clear SkippedVersion in UserDefaults
110 |
111 | ```[[LTUpdate shared] clearSkippedVersion];```
112 |
113 | ### Shortcuts
114 |
115 | * ```NSString *humanReadableFileSize(unsigned long long int size);``` formats file size to "123.45MB" style;
116 | * ```static NSString *kAppName();``` is the display name of current App;
117 | * ```static NSString *kAppVersion();``` the version of current App.
118 | * ```static NSString *LTI18N(NSString *key);``` return localized string in LTUpdate.strings.
119 |
120 | Learn more in [LTUpdate.h](https://github.com/lexrus/LTUpdate/blob/master/LTUpdate/LTUpdate.h).
121 |
122 |
123 | ## AppStore Submissions
124 |
125 | The AppStore reviewer will not see the alert. Because the submitted version is always greater than the online version in AppStore.
126 |
127 |
128 | ## Testing & Building the demo
129 |
130 | Testing coverage is about 70% exclude UI functions.
131 |
132 | Install [JSONKit](https://github.com/johnezang/JSONKit) before build.
133 | ```
134 | git submodule init
135 | git submodule update
136 | ```
137 |
138 | ## License
139 | This code is distributed under the terms and conditions of the MIT license. See LTUpdate.h for details.
140 |
--------------------------------------------------------------------------------
/LTUpdate/LTUpdate.m:
--------------------------------------------------------------------------------
1 | //
2 | // LTUpdate.h
3 | // LTUpdate
4 | //
5 | // Created by Lex Tang on 18/2/13.
6 | //
7 | // The MIT License (MIT)
8 | // Copyright © 2013 Lex Tang, http://LexTang.com
9 | //
10 | // Permission is hereby granted, free of charge, to any person obtaining a copy
11 | // of this software and associated documentation files (the “Software”), to deal
12 | // in the Software without restriction, including without limitation the rights
13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | // copies of the Software, and to permit persons to whom the Software is
15 | // furnished to do so, subject to the following conditions:
16 | //
17 | // The above copyright notice and this permission notice shall be included in
18 | // all copies or substantial portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 | // THE SOFTWARE.
27 | //
28 |
29 | #import "LTUpdate.h"
30 |
31 | #define kAppStoreFormat @"http://itunes.apple.com/app/id%ld"
32 | #define kiTunesAPILookUpFormat @"http://itunes.apple.com/lookup?id=%ld"
33 | // Alternative URL:
34 | // @define kiTunesLookUpFormat @"http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/wa/wsLookup?id=%ld"
35 |
36 |
37 | static int kHourlyDuration = 3600;
38 | static int kDailyDuration = 86400;
39 | static int kWeeklyDuration = 604800;
40 | static int kMonthlyDuration = 2592000;
41 |
42 | static dispatch_queue_t get_update_queue() {
43 | static dispatch_once_t updateQueueToken;
44 | static dispatch_queue_t _updateQueue;
45 |
46 | dispatch_once(&updateQueueToken, ^{
47 | _updateQueue = dispatch_queue_create("com.lextang.update", NULL);
48 | });
49 | return _updateQueue;
50 | };
51 |
52 | NSDate *parseRFC3339Date(NSString *dateString) {
53 | NSDateFormatter *rfc3339TimestampFormatterWithTimeZone = [[NSDateFormatter alloc] init];
54 | NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
55 | [rfc3339TimestampFormatterWithTimeZone setLocale:locale];
56 | [rfc3339TimestampFormatterWithTimeZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
57 |
58 | NSDate *theDate = nil;
59 | NSError *error = nil;
60 | if (![rfc3339TimestampFormatterWithTimeZone getObjectValue:&theDate forString:dateString range:nil error:&error]) {
61 | }
62 |
63 | [locale release];
64 | locale = nil;
65 | [rfc3339TimestampFormatterWithTimeZone release];
66 | rfc3339TimestampFormatterWithTimeZone = nil;
67 | return theDate;
68 | }
69 |
70 | @implementation LTUpdateVersionDetails
71 |
72 | - (id)copyWithZone:(NSZone *)zone
73 | {
74 | LTUpdateVersionDetails *copy = [[[self class] allocWithZone:zone] init];
75 | copy.version = [[self.version copyWithZone:zone] autorelease];
76 | copy.releaseNotes = [[self.releaseNotes copyWithZone:zone] autorelease];
77 | copy.releaseDate = [[self.releaseDate copyWithZone:zone] autorelease];
78 | copy.fileSizeBytes = self.fileSizeBytes;
79 | return copy;
80 | }
81 |
82 | @end
83 |
84 |
85 | @interface LTUpdate ()
86 |
87 | @end
88 |
89 |
90 | @implementation LTUpdate
91 |
92 | @synthesize latestVersion = _latestVersion;
93 | @synthesize completionBlock = _completionBlock;
94 |
95 | static long _appStoreID;
96 |
97 | + (id)shared {
98 | static LTUpdate *instance;
99 | static dispatch_once_t onceToken;
100 | dispatch_once(&onceToken, ^{
101 | instance = [[LTUpdate alloc] init];
102 | _appStoreID = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"APP_STORE_ID"] longValue];
103 | });
104 | return instance;
105 | }
106 |
107 | - (long)appStoreID {
108 | return _appStoreID;
109 | }
110 |
111 | - (void)update {
112 | [self update:^(BOOL isNewVersionAvailable, LTUpdateVersionDetails *versionDetails) {
113 | if (isNewVersionAvailable) {
114 | [self alertLatestVersion:LTUpdateOption | LTUpdateSkip];
115 | }
116 | }];
117 | }
118 |
119 | - (void)update:(LTUpdateCallback)callback {
120 | [self update:LTUpdateDaily complete:callback];
121 | }
122 |
123 | - (void)update:(LTUpdatePeroid)peroid complete:(LTUpdateCallback)callback {
124 | NSAssert(self.appStoreID > 0,
125 | @"Please add a Number field in {{}}-Info.plist named APP_STORE_ID and your App ID as value.");
126 | #pragma clang diagnostic push
127 | #pragma clang diagnostic ignored "-Warc-retain-cycles"
128 | if (callback)
129 | self.completionBlock = callback;
130 | #pragma clang diagnostic pop
131 |
132 | double lastUpdateInterval = [self lastUpdateInterval];
133 | double timestamp = [[NSDate date] timeIntervalSince1970];
134 |
135 | if ((peroid == LTUpdateHourly && timestamp - lastUpdateInterval < kHourlyDuration) ||
136 | (peroid == LTUpdateDaily && timestamp - lastUpdateInterval < kDailyDuration) ||
137 | (peroid == LTUpdateWeekly && timestamp - lastUpdateInterval < kWeeklyDuration) ||
138 | (peroid == LTUpdateMonthly && timestamp - lastUpdateInterval < kMonthlyDuration)) {
139 | if (self.completionBlock)
140 | self.completionBlock(NO, nil);
141 | return;
142 | }
143 |
144 | __weak __typeof (&*self) weakSelf = self;
145 | dispatch_async(get_update_queue(), ^{
146 | __strong __typeof (&*weakSelf) strongSelf = weakSelf;
147 |
148 | [strongSelf parseJSON:[strongSelf fetchJSON]];
149 |
150 | if (!strongSelf.completionBlock) return;
151 |
152 | if ([strongSelf latestVersion]) {
153 | if (strongSelf.completionBlock) {
154 | dispatch_sync(dispatch_get_main_queue(), ^{
155 | strongSelf.completionBlock(YES, [strongSelf latestVersion]);
156 | });
157 | }
158 | } else {
159 | dispatch_sync(dispatch_get_main_queue(), ^{
160 | strongSelf.completionBlock(NO, nil);
161 | });
162 | }
163 | });
164 | }
165 |
166 | #pragma mark - JSON
167 |
168 | - (NSData *)fetchJSON {
169 | NSString *urlString = [NSString stringWithFormat:kiTunesAPILookUpFormat, [self appStoreID]];
170 | NSURL *url = [NSURL URLWithString:urlString];
171 | NSURLRequest *request = [NSURLRequest requestWithURL:url
172 | cachePolicy:NSURLRequestReloadRevalidatingCacheData
173 | timeoutInterval:30];
174 | NSError *error = nil;
175 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:&error];
176 | if (!error) {
177 | [self setLastUpdateInterval];
178 | return responseData;
179 | }
180 | return nil;
181 | }
182 |
183 | - (id)decodeJSON:(NSData *)data {
184 | if (!data) return nil;
185 | id _targetClass = data;
186 | SEL _targetSelector = NSSelectorFromString(@"objectFromJSONDataWithParseOptions:error");
187 | BOOL hasJSONKit = YES;
188 |
189 | if (!(_targetSelector && [data respondsToSelector:_targetSelector])) {
190 | _targetSelector = NSSelectorFromString(@"JSONObjectWithData:options:error:");
191 | _targetClass = NSClassFromString(@"NSJSONSerialization");
192 | hasJSONKit = NO;
193 | if (!_targetClass) return nil;
194 | }
195 |
196 | NSInvocation *invocation = [NSInvocation
197 | invocationWithMethodSignature:[_targetClass methodSignatureForSelector:_targetSelector]];
198 | invocation.target = _targetClass;
199 | invocation.selector = _targetSelector;
200 |
201 | if (!hasJSONKit)
202 | [invocation setArgument:&data atIndex:2];
203 | NSUInteger optionFlags = 0;
204 | [invocation setArgument:&optionFlags atIndex:hasJSONKit ? 2 : 3];
205 | // NSError *error = nil;
206 | // [invocation setArgument:&error atIndex:hasJSONKit ? 3 : 4];
207 |
208 | [invocation invoke];
209 | __unsafe_unretained id JSON = nil;
210 | [invocation getReturnValue:&JSON];
211 | return JSON;
212 | }
213 |
214 | - (void)parseJSON:(NSData *)jsonData {
215 | id json = [self decodeJSON:jsonData];
216 | if (json && [json isKindOfClass:[NSDictionary class]]) {
217 | NSArray *results = [json objectForKey:@"results"];
218 | if (results && [results isKindOfClass:[NSArray class]] && [results count] > 0) {
219 | NSDictionary *versionDetail = [results[0] copy];
220 | if (versionDetail && [versionDetail isKindOfClass:[NSDictionary class]]) {
221 | NSString *newVersion = [versionDetail objectForKey:@"version"];
222 | NSString *releaseNotes = [versionDetail objectForKey:@"releaseNotes"];
223 | NSString *releaseDate = [versionDetail objectForKey:@"releaseDate"];
224 | NSString *fileSizeBytes = [versionDetail objectForKey:@"fileSizeBytes"];
225 | if (newVersion &&
226 | [newVersion isKindOfClass:[NSString class]] &&
227 | [newVersion compare:kAppVersion() options:NSNumericSearch] == NSOrderedDescending &&
228 | ![self isVersionSkipped:newVersion]) {
229 | _latestVersion = [[LTUpdateVersionDetails alloc] init];
230 | _latestVersion.version = [newVersion copy];
231 | if (releaseNotes && [releaseNotes length] > 0) {
232 | _latestVersion.releaseNotes = [releaseNotes copy];
233 | }
234 | if (releaseDate) {
235 | _latestVersion.releaseDate = parseRFC3339Date(releaseDate);
236 | }
237 | if (fileSizeBytes && [fileSizeBytes longLongValue] > 0) {
238 | _latestVersion.fileSizeBytes = [fileSizeBytes longLongValue];
239 | }
240 | } else {
241 | _latestVersion = nil;
242 | }
243 | }
244 | }
245 | }
246 | }
247 |
248 | #pragma mark - Update message
249 |
250 | - (NSString*)updateMessage {
251 | return [NSString stringWithFormat:
252 | LTI18N(@"%@ %@ is now available. You have %@. Would you like to download(%@) it now?"),
253 | kAppName(),
254 | self.latestVersion.version,
255 | kAppVersion(),
256 | humanReadableFileSize(self.latestVersion.fileSizeBytes)];
257 | }
258 |
259 | #pragma mark - Update interval
260 |
261 | - (double)lastUpdateInterval {
262 | return [[NSUserDefaults standardUserDefaults] doubleForKey:@"LTLastUpdateDate"];
263 | }
264 |
265 | - (void)setLastUpdateInterval {
266 | double timestamp = [[NSDate date] timeIntervalSince1970];
267 | [[NSUserDefaults standardUserDefaults] setDouble:timestamp forKey:@"LTLastUpdateDate"];
268 | [[NSUserDefaults standardUserDefaults] synchronize];
269 | }
270 |
271 | #pragma mark - Skipped version
272 |
273 | - (NSString *)versionSkipped {
274 | return [[NSUserDefaults standardUserDefaults] stringForKey:@"LTSkippedVersion"];
275 | }
276 |
277 | - (void)setVersionSkipped:(NSString *)version {
278 | [[NSUserDefaults standardUserDefaults] setObject:version forKey:@"LTSkippedVersion"];
279 | [[NSUserDefaults standardUserDefaults] synchronize];
280 | }
281 |
282 | - (BOOL)isVersionSkipped:(NSString *)version {
283 | return [version compare:[self versionSkipped] options:NSNumericSearch] == NSOrderedSame;
284 | }
285 |
286 | - (void)skipVersion:(NSString *)version {
287 | [self setVersionSkipped:version];
288 | }
289 |
290 | - (void)clearSkippedVersion {
291 | [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"LTSkippedVersion"];
292 | [[NSUserDefaults standardUserDefaults] synchronize];
293 | }
294 |
295 | #pragma mark - Default Alert
296 |
297 | - (void)__attribute__((unused)) alertLatestVersion:(LTUpdateOptions)alertOptions {
298 | UIAlertView *alertView = [[UIAlertView alloc] init];
299 | [alertView setTitle:LTI18N(@"A new version is available!")];
300 | [alertView setMessage:[self updateMessage]];
301 |
302 | [alertView addButtonWithTitle:LTI18N(@"Update")];
303 |
304 | if (alertOptions & LTUpdateForce) {
305 |
306 | } else {
307 | if (alertOptions & LTUpdateSkip) {
308 | [alertView addButtonWithTitle:LTI18N(@"Skip This Version")];
309 | }
310 | [alertView addButtonWithTitle:LTI18N(@"Remind Me Later")];
311 | }
312 |
313 | [alertView setDelegate:self];
314 | [alertView show];
315 | [alertView release];
316 | alertView = nil;
317 | }
318 |
319 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
320 | if (buttonIndex == 0) {
321 | NSString *appStoreURL = [NSString stringWithFormat:kAppStoreFormat, [self appStoreID]];
322 | NSURL *url = [NSURL URLWithString:appStoreURL];
323 | [[UIApplication sharedApplication] openURL:url];
324 | } else if ([[alertView buttonTitleAtIndex:buttonIndex]
325 | isEqualToString:LTI18N(@"Skip This Version")]) {
326 | [self skipVersion:[[self latestVersion] version]];
327 | }
328 | }
329 |
330 | #pragma mark - Notification
331 |
332 | - (void)updateAndPush
333 | {
334 | [self updateAndPush:LTUpdateDaily];
335 | }
336 |
337 | - (void)updateAndPush:(LTUpdatePeroid)peroid
338 | {
339 | static dispatch_once_t observerToken;
340 | dispatch_once(&observerToken, ^{
341 | [[NSNotificationCenter defaultCenter] addObserver:self
342 | selector:@selector(pushLatestVersion)
343 | name:UIApplicationDidEnterBackgroundNotification
344 | object:nil];
345 | });
346 | [self update:peroid complete:nil];
347 | }
348 |
349 | - (void)__attribute__((unused)) pushLatestVersion
350 | {
351 | [self pushLatestVersion:nil];
352 | }
353 |
354 | - (void)pushLatestVersion:(UILocalNotification *)notification
355 | {
356 | if (!self.latestVersion) return;
357 | if (!notification) {
358 | notification = [[UILocalNotification alloc] init];
359 | notification.timeZone = [NSTimeZone defaultTimeZone];
360 | notification.fireDate = [[NSDate date] dateByAddingTimeInterval:1.5f];
361 | notification.alertBody = [self updateMessage];
362 | notification.alertAction = LTI18N(@"Update");
363 | }
364 | [[UIApplication sharedApplication] scheduleLocalNotification:notification];
365 | [[NSNotificationCenter defaultCenter] removeObserver:self
366 | name:UIApplicationDidEnterBackgroundNotification
367 | object:nil];
368 | }
369 |
370 | - (void)__attribute__((unused)) reduceNotification:(UILocalNotification*)notification
371 | {
372 | [self reduceNotification:notification then:LTUpdateNotifyOpenAppStore];
373 | }
374 |
375 | - (void)reduceNotification:(UILocalNotification *)notification then:(LTUpdateNotifyActions)action
376 | {
377 | if ([notification.alertAction isEqualToString:LTI18N(@"Update")]) {
378 | [[UIApplication sharedApplication] cancelLocalNotification:notification];
379 | if (action == LTUpdateNotifyOpenAppStore) {
380 | [self openAppStore];
381 | } else if (action == LTUpdateNotifyThenAlert) {
382 | [self alertLatestVersion:LTUpdateSkip|LTUpdateOption];
383 | }
384 | }
385 | }
386 |
387 | #pragma mark - Open AppStore
388 |
389 | - (void)openAppStore
390 | {
391 | NSString *appStoreURL = [NSString stringWithFormat:kAppStoreFormat, [self appStoreID]];
392 | NSURL *url = [NSURL URLWithString:appStoreURL];
393 | [[UIApplication sharedApplication] openURL:url];
394 | }
395 |
396 |
397 | @end
398 |
--------------------------------------------------------------------------------
/LTUpdate Demo/LTUpdate Demo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | D71AFD9316DDF2170099121A /* LTUpdate.strings in Resources */ = {isa = PBXBuildFile; fileRef = D71AFD7A16DDF2170099121A /* LTUpdate.strings */; };
11 | D71AFD9416DDF2170099121A /* LTUpdate.strings in Resources */ = {isa = PBXBuildFile; fileRef = D71AFD7A16DDF2170099121A /* LTUpdate.strings */; };
12 | D779146116D23BB600BDF086 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D779146016D23BB600BDF086 /* UIKit.framework */; };
13 | D779146316D23BB600BDF086 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D779146216D23BB600BDF086 /* Foundation.framework */; };
14 | D779146516D23BB600BDF086 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D779146416D23BB600BDF086 /* CoreGraphics.framework */; };
15 | D779146B16D23BB600BDF086 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D779146916D23BB600BDF086 /* InfoPlist.strings */; };
16 | D779146D16D23BB600BDF086 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D779146C16D23BB600BDF086 /* main.m */; };
17 | D779147116D23BB700BDF086 /* LTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D779147016D23BB700BDF086 /* LTAppDelegate.m */; };
18 | D779147316D23BB700BDF086 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = D779147216D23BB700BDF086 /* Default.png */; };
19 | D779147516D23BB700BDF086 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D779147416D23BB700BDF086 /* Default@2x.png */; };
20 | D779147716D23BB700BDF086 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D779147616D23BB700BDF086 /* Default-568h@2x.png */; };
21 | D779147F16D23BB700BDF086 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D779147E16D23BB700BDF086 /* SenTestingKit.framework */; };
22 | D779148016D23BB700BDF086 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D779146016D23BB600BDF086 /* UIKit.framework */; };
23 | D779148116D23BB700BDF086 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D779146216D23BB600BDF086 /* Foundation.framework */; };
24 | D779148916D23BB700BDF086 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D779148716D23BB700BDF086 /* InfoPlist.strings */; };
25 | D779148C16D23BB700BDF086 /* LTUpdate_DemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D779148B16D23BB700BDF086 /* LTUpdate_DemoTests.m */; };
26 | D779149816D23C3100BDF086 /* LTUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = D779149716D23C3100BDF086 /* LTUpdate.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
27 | D779149916D23C3100BDF086 /* LTUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = D779149716D23C3100BDF086 /* LTUpdate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
28 | D7953BA716DB410600700B2F /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = D7953BA316DB410600700B2F /* JSONKit.m */; };
29 | D7953BA816DB410600700B2F /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = D7953BA316DB410600700B2F /* JSONKit.m */; };
30 | /* End PBXBuildFile section */
31 |
32 | /* Begin PBXContainerItemProxy section */
33 | D779148216D23BB700BDF086 /* PBXContainerItemProxy */ = {
34 | isa = PBXContainerItemProxy;
35 | containerPortal = D779145516D23BB600BDF086 /* Project object */;
36 | proxyType = 1;
37 | remoteGlobalIDString = D779145C16D23BB600BDF086;
38 | remoteInfo = "LTUpdate Demo";
39 | };
40 | /* End PBXContainerItemProxy section */
41 |
42 | /* Begin PBXFileReference section */
43 | D71AFD7B16DDF2170099121A /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LTUpdate.strings; sourceTree = ""; };
44 | D71AFD7C16DDF2170099121A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/LTUpdate.strings; sourceTree = ""; };
45 | D71AFD7D16DDF2170099121A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/LTUpdate.strings; sourceTree = ""; };
46 | D71AFD7E16DDF2170099121A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/LTUpdate.strings; sourceTree = ""; };
47 | D71AFD7F16DDF2170099121A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LTUpdate.strings; sourceTree = ""; };
48 | D71AFD8016DDF2170099121A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LTUpdate.strings; sourceTree = ""; };
49 | D71AFD8116DDF2170099121A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/LTUpdate.strings; sourceTree = ""; };
50 | D71AFD8216DDF2170099121A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/LTUpdate.strings; sourceTree = ""; };
51 | D71AFD8316DDF2170099121A /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/LTUpdate.strings; sourceTree = ""; };
52 | D71AFD8416DDF2170099121A /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/LTUpdate.strings; sourceTree = ""; };
53 | D71AFD8516DDF2170099121A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/LTUpdate.strings; sourceTree = ""; };
54 | D71AFD8616DDF2170099121A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/LTUpdate.strings; sourceTree = ""; };
55 | D71AFD8716DDF2170099121A /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/LTUpdate.strings"; sourceTree = ""; };
56 | D71AFD8816DDF2170099121A /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LTUpdate.strings"; sourceTree = ""; };
57 | D71AFD8916DDF2170099121A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/LTUpdate.strings; sourceTree = ""; };
58 | D71AFD8A16DDF2170099121A /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/LTUpdate.strings; sourceTree = ""; };
59 | D71AFD8B16DDF2170099121A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/LTUpdate.strings; sourceTree = ""; };
60 | D71AFD8C16DDF2170099121A /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/LTUpdate.strings; sourceTree = ""; };
61 | D71AFD8D16DDF2170099121A /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/LTUpdate.strings; sourceTree = ""; };
62 | D71AFD8E16DDF2170099121A /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/LTUpdate.strings; sourceTree = ""; };
63 | D71AFD8F16DDF2170099121A /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/LTUpdate.strings; sourceTree = ""; };
64 | D71AFD9016DDF2170099121A /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LTUpdate.strings"; sourceTree = ""; };
65 | D71AFD9216DDF2170099121A /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/LTUpdate.strings"; sourceTree = ""; };
66 | D71AFD9516DE01A20099121A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/LTUpdate.strings; sourceTree = ""; };
67 | D73EFAD016DE475E008C2CD8 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/LTUpdate.strings"; sourceTree = ""; };
68 | D779145D16D23BB600BDF086 /* LTUpdate Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "LTUpdate Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
69 | D779146016D23BB600BDF086 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
70 | D779146216D23BB600BDF086 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
71 | D779146416D23BB600BDF086 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
72 | D779146816D23BB600BDF086 /* LTUpdate Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LTUpdate Demo-Info.plist"; sourceTree = ""; };
73 | D779146A16D23BB600BDF086 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
74 | D779146C16D23BB600BDF086 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
75 | D779146E16D23BB700BDF086 /* LTUpdate Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LTUpdate Demo-Prefix.pch"; sourceTree = ""; };
76 | D779146F16D23BB700BDF086 /* LTAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTAppDelegate.h; sourceTree = ""; };
77 | D779147016D23BB700BDF086 /* LTAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LTAppDelegate.m; sourceTree = ""; };
78 | D779147216D23BB700BDF086 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; };
79 | D779147416D23BB700BDF086 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; };
80 | D779147616D23BB700BDF086 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
81 | D779147D16D23BB700BDF086 /* LTUpdate DemoTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LTUpdate DemoTests.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
82 | D779147E16D23BB700BDF086 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
83 | D779148616D23BB700BDF086 /* LTUpdate DemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LTUpdate DemoTests-Info.plist"; sourceTree = ""; };
84 | D779148816D23BB700BDF086 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
85 | D779148A16D23BB700BDF086 /* LTUpdate_DemoTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LTUpdate_DemoTests.h; sourceTree = ""; };
86 | D779148B16D23BB700BDF086 /* LTUpdate_DemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LTUpdate_DemoTests.m; sourceTree = ""; };
87 | D779149616D23C3100BDF086 /* LTUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LTUpdate.h; sourceTree = ""; };
88 | D779149716D23C3100BDF086 /* LTUpdate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LTUpdate.m; sourceTree = ""; };
89 | D7953BA216DB410600700B2F /* JSONKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONKit.h; sourceTree = ""; };
90 | D7953BA316DB410600700B2F /* JSONKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONKit.m; sourceTree = ""; };
91 | /* End PBXFileReference section */
92 |
93 | /* Begin PBXFrameworksBuildPhase section */
94 | D779145A16D23BB600BDF086 /* Frameworks */ = {
95 | isa = PBXFrameworksBuildPhase;
96 | buildActionMask = 2147483647;
97 | files = (
98 | D779146116D23BB600BDF086 /* UIKit.framework in Frameworks */,
99 | D779146316D23BB600BDF086 /* Foundation.framework in Frameworks */,
100 | D779146516D23BB600BDF086 /* CoreGraphics.framework in Frameworks */,
101 | );
102 | runOnlyForDeploymentPostprocessing = 0;
103 | };
104 | D779147916D23BB700BDF086 /* Frameworks */ = {
105 | isa = PBXFrameworksBuildPhase;
106 | buildActionMask = 2147483647;
107 | files = (
108 | D779147F16D23BB700BDF086 /* SenTestingKit.framework in Frameworks */,
109 | D779148016D23BB700BDF086 /* UIKit.framework in Frameworks */,
110 | D779148116D23BB700BDF086 /* Foundation.framework in Frameworks */,
111 | );
112 | runOnlyForDeploymentPostprocessing = 0;
113 | };
114 | /* End PBXFrameworksBuildPhase section */
115 |
116 | /* Begin PBXGroup section */
117 | D71AFD7916DDF2170099121A /* LTI18N */ = {
118 | isa = PBXGroup;
119 | children = (
120 | D71AFD7A16DDF2170099121A /* LTUpdate.strings */,
121 | );
122 | path = LTI18N;
123 | sourceTree = "";
124 | };
125 | D779145416D23BB600BDF086 = {
126 | isa = PBXGroup;
127 | children = (
128 | D7953BA016DB410600700B2F /* JSONKit */,
129 | D779149516D23C1700BDF086 /* LTUpdate */,
130 | D779146616D23BB600BDF086 /* LTUpdate Demo */,
131 | D779148416D23BB700BDF086 /* LTUpdate DemoTests */,
132 | D779145F16D23BB600BDF086 /* Frameworks */,
133 | D779145E16D23BB600BDF086 /* Products */,
134 | );
135 | sourceTree = "";
136 | };
137 | D779145E16D23BB600BDF086 /* Products */ = {
138 | isa = PBXGroup;
139 | children = (
140 | D779145D16D23BB600BDF086 /* LTUpdate Demo.app */,
141 | D779147D16D23BB700BDF086 /* LTUpdate DemoTests.octest */,
142 | );
143 | name = Products;
144 | sourceTree = "";
145 | };
146 | D779145F16D23BB600BDF086 /* Frameworks */ = {
147 | isa = PBXGroup;
148 | children = (
149 | D779146016D23BB600BDF086 /* UIKit.framework */,
150 | D779146216D23BB600BDF086 /* Foundation.framework */,
151 | D779146416D23BB600BDF086 /* CoreGraphics.framework */,
152 | D779147E16D23BB700BDF086 /* SenTestingKit.framework */,
153 | );
154 | name = Frameworks;
155 | sourceTree = "";
156 | };
157 | D779146616D23BB600BDF086 /* LTUpdate Demo */ = {
158 | isa = PBXGroup;
159 | children = (
160 | D779146F16D23BB700BDF086 /* LTAppDelegate.h */,
161 | D779147016D23BB700BDF086 /* LTAppDelegate.m */,
162 | D779146716D23BB600BDF086 /* Supporting Files */,
163 | );
164 | path = "LTUpdate Demo";
165 | sourceTree = "";
166 | };
167 | D779146716D23BB600BDF086 /* Supporting Files */ = {
168 | isa = PBXGroup;
169 | children = (
170 | D779146816D23BB600BDF086 /* LTUpdate Demo-Info.plist */,
171 | D779146916D23BB600BDF086 /* InfoPlist.strings */,
172 | D779146C16D23BB600BDF086 /* main.m */,
173 | D779146E16D23BB700BDF086 /* LTUpdate Demo-Prefix.pch */,
174 | D779147216D23BB700BDF086 /* Default.png */,
175 | D779147416D23BB700BDF086 /* Default@2x.png */,
176 | D779147616D23BB700BDF086 /* Default-568h@2x.png */,
177 | );
178 | name = "Supporting Files";
179 | sourceTree = "";
180 | };
181 | D779148416D23BB700BDF086 /* LTUpdate DemoTests */ = {
182 | isa = PBXGroup;
183 | children = (
184 | D779148A16D23BB700BDF086 /* LTUpdate_DemoTests.h */,
185 | D779148B16D23BB700BDF086 /* LTUpdate_DemoTests.m */,
186 | D779148516D23BB700BDF086 /* Supporting Files */,
187 | );
188 | path = "LTUpdate DemoTests";
189 | sourceTree = "";
190 | };
191 | D779148516D23BB700BDF086 /* Supporting Files */ = {
192 | isa = PBXGroup;
193 | children = (
194 | D779148616D23BB700BDF086 /* LTUpdate DemoTests-Info.plist */,
195 | D779148716D23BB700BDF086 /* InfoPlist.strings */,
196 | );
197 | name = "Supporting Files";
198 | sourceTree = "";
199 | };
200 | D779149516D23C1700BDF086 /* LTUpdate */ = {
201 | isa = PBXGroup;
202 | children = (
203 | D71AFD7916DDF2170099121A /* LTI18N */,
204 | D779149616D23C3100BDF086 /* LTUpdate.h */,
205 | D779149716D23C3100BDF086 /* LTUpdate.m */,
206 | );
207 | name = LTUpdate;
208 | path = ../LTUpdate;
209 | sourceTree = "";
210 | };
211 | D7953BA016DB410600700B2F /* JSONKit */ = {
212 | isa = PBXGroup;
213 | children = (
214 | D7953BA216DB410600700B2F /* JSONKit.h */,
215 | D7953BA316DB410600700B2F /* JSONKit.m */,
216 | );
217 | name = JSONKit;
218 | path = ../JSONKit;
219 | sourceTree = "";
220 | };
221 | /* End PBXGroup section */
222 |
223 | /* Begin PBXNativeTarget section */
224 | D779145C16D23BB600BDF086 /* LTUpdate Demo */ = {
225 | isa = PBXNativeTarget;
226 | buildConfigurationList = D779148F16D23BB700BDF086 /* Build configuration list for PBXNativeTarget "LTUpdate Demo" */;
227 | buildPhases = (
228 | D779145916D23BB600BDF086 /* Sources */,
229 | D779145A16D23BB600BDF086 /* Frameworks */,
230 | D779145B16D23BB600BDF086 /* Resources */,
231 | );
232 | buildRules = (
233 | );
234 | dependencies = (
235 | );
236 | name = "LTUpdate Demo";
237 | productName = "LTUpdate Demo";
238 | productReference = D779145D16D23BB600BDF086 /* LTUpdate Demo.app */;
239 | productType = "com.apple.product-type.application";
240 | };
241 | D779147C16D23BB700BDF086 /* LTUpdate DemoTests */ = {
242 | isa = PBXNativeTarget;
243 | buildConfigurationList = D779149216D23BB700BDF086 /* Build configuration list for PBXNativeTarget "LTUpdate DemoTests" */;
244 | buildPhases = (
245 | D779147816D23BB700BDF086 /* Sources */,
246 | D779147916D23BB700BDF086 /* Frameworks */,
247 | D779147A16D23BB700BDF086 /* Resources */,
248 | D779147B16D23BB700BDF086 /* ShellScript */,
249 | );
250 | buildRules = (
251 | );
252 | dependencies = (
253 | D779148316D23BB700BDF086 /* PBXTargetDependency */,
254 | );
255 | name = "LTUpdate DemoTests";
256 | productName = "LTUpdate DemoTests";
257 | productReference = D779147D16D23BB700BDF086 /* LTUpdate DemoTests.octest */;
258 | productType = "com.apple.product-type.bundle";
259 | };
260 | /* End PBXNativeTarget section */
261 |
262 | /* Begin PBXProject section */
263 | D779145516D23BB600BDF086 /* Project object */ = {
264 | isa = PBXProject;
265 | attributes = {
266 | CLASSPREFIX = LT;
267 | LastUpgradeCheck = 0460;
268 | ORGANIZATIONNAME = "Lex Tang";
269 | };
270 | buildConfigurationList = D779145816D23BB600BDF086 /* Build configuration list for PBXProject "LTUpdate Demo" */;
271 | compatibilityVersion = "Xcode 3.2";
272 | developmentRegion = English;
273 | hasScannedForEncodings = 0;
274 | knownRegions = (
275 | en,
276 | "zh-Hans",
277 | "zh-Hant",
278 | fr,
279 | ja,
280 | de,
281 | es,
282 | it,
283 | pt,
284 | "pt-PT",
285 | nl,
286 | sv,
287 | da,
288 | ru,
289 | pl,
290 | "pt-BR",
291 | ko,
292 | ar,
293 | cs,
294 | tr,
295 | th,
296 | ro,
297 | sk,
298 | uk,
299 | "zh-Hant-TW",
300 | "zh-Hant-HK",
301 | sl,
302 | );
303 | mainGroup = D779145416D23BB600BDF086;
304 | productRefGroup = D779145E16D23BB600BDF086 /* Products */;
305 | projectDirPath = "";
306 | projectRoot = "";
307 | targets = (
308 | D779145C16D23BB600BDF086 /* LTUpdate Demo */,
309 | D779147C16D23BB700BDF086 /* LTUpdate DemoTests */,
310 | );
311 | };
312 | /* End PBXProject section */
313 |
314 | /* Begin PBXResourcesBuildPhase section */
315 | D779145B16D23BB600BDF086 /* Resources */ = {
316 | isa = PBXResourcesBuildPhase;
317 | buildActionMask = 2147483647;
318 | files = (
319 | D779146B16D23BB600BDF086 /* InfoPlist.strings in Resources */,
320 | D779147316D23BB700BDF086 /* Default.png in Resources */,
321 | D779147516D23BB700BDF086 /* Default@2x.png in Resources */,
322 | D779147716D23BB700BDF086 /* Default-568h@2x.png in Resources */,
323 | D71AFD9316DDF2170099121A /* LTUpdate.strings in Resources */,
324 | );
325 | runOnlyForDeploymentPostprocessing = 0;
326 | };
327 | D779147A16D23BB700BDF086 /* Resources */ = {
328 | isa = PBXResourcesBuildPhase;
329 | buildActionMask = 2147483647;
330 | files = (
331 | D779148916D23BB700BDF086 /* InfoPlist.strings in Resources */,
332 | D71AFD9416DDF2170099121A /* LTUpdate.strings in Resources */,
333 | );
334 | runOnlyForDeploymentPostprocessing = 0;
335 | };
336 | /* End PBXResourcesBuildPhase section */
337 |
338 | /* Begin PBXShellScriptBuildPhase section */
339 | D779147B16D23BB700BDF086 /* ShellScript */ = {
340 | isa = PBXShellScriptBuildPhase;
341 | buildActionMask = 2147483647;
342 | files = (
343 | );
344 | inputPaths = (
345 | );
346 | outputPaths = (
347 | );
348 | runOnlyForDeploymentPostprocessing = 0;
349 | shellPath = /bin/sh;
350 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
351 | };
352 | /* End PBXShellScriptBuildPhase section */
353 |
354 | /* Begin PBXSourcesBuildPhase section */
355 | D779145916D23BB600BDF086 /* Sources */ = {
356 | isa = PBXSourcesBuildPhase;
357 | buildActionMask = 2147483647;
358 | files = (
359 | D779146D16D23BB600BDF086 /* main.m in Sources */,
360 | D779147116D23BB700BDF086 /* LTAppDelegate.m in Sources */,
361 | D779149816D23C3100BDF086 /* LTUpdate.m in Sources */,
362 | D7953BA716DB410600700B2F /* JSONKit.m in Sources */,
363 | );
364 | runOnlyForDeploymentPostprocessing = 0;
365 | };
366 | D779147816D23BB700BDF086 /* Sources */ = {
367 | isa = PBXSourcesBuildPhase;
368 | buildActionMask = 2147483647;
369 | files = (
370 | D779148C16D23BB700BDF086 /* LTUpdate_DemoTests.m in Sources */,
371 | D779149916D23C3100BDF086 /* LTUpdate.m in Sources */,
372 | D7953BA816DB410600700B2F /* JSONKit.m in Sources */,
373 | );
374 | runOnlyForDeploymentPostprocessing = 0;
375 | };
376 | /* End PBXSourcesBuildPhase section */
377 |
378 | /* Begin PBXTargetDependency section */
379 | D779148316D23BB700BDF086 /* PBXTargetDependency */ = {
380 | isa = PBXTargetDependency;
381 | target = D779145C16D23BB600BDF086 /* LTUpdate Demo */;
382 | targetProxy = D779148216D23BB700BDF086 /* PBXContainerItemProxy */;
383 | };
384 | /* End PBXTargetDependency section */
385 |
386 | /* Begin PBXVariantGroup section */
387 | D71AFD7A16DDF2170099121A /* LTUpdate.strings */ = {
388 | isa = PBXVariantGroup;
389 | children = (
390 | D71AFD7B16DDF2170099121A /* ar */,
391 | D71AFD7C16DDF2170099121A /* cs */,
392 | D71AFD7D16DDF2170099121A /* da */,
393 | D71AFD7E16DDF2170099121A /* de */,
394 | D71AFD7F16DDF2170099121A /* en */,
395 | D71AFD8016DDF2170099121A /* es */,
396 | D71AFD8116DDF2170099121A /* fr */,
397 | D71AFD8216DDF2170099121A /* it */,
398 | D71AFD8316DDF2170099121A /* ja */,
399 | D71AFD8416DDF2170099121A /* ko */,
400 | D71AFD8516DDF2170099121A /* nl */,
401 | D71AFD8616DDF2170099121A /* pl */,
402 | D71AFD8716DDF2170099121A /* pt-BR */,
403 | D71AFD8816DDF2170099121A /* pt-PT */,
404 | D71AFD8916DDF2170099121A /* ro */,
405 | D71AFD8A16DDF2170099121A /* ru */,
406 | D71AFD8B16DDF2170099121A /* sk */,
407 | D71AFD8C16DDF2170099121A /* sv */,
408 | D71AFD8D16DDF2170099121A /* th */,
409 | D71AFD8E16DDF2170099121A /* tr */,
410 | D71AFD8F16DDF2170099121A /* uk */,
411 | D71AFD9016DDF2170099121A /* zh-Hans */,
412 | D71AFD9216DDF2170099121A /* zh-Hant-TW */,
413 | D71AFD9516DE01A20099121A /* sl */,
414 | D73EFAD016DE475E008C2CD8 /* zh-Hant */,
415 | );
416 | name = LTUpdate.strings;
417 | sourceTree = "";
418 | };
419 | D779146916D23BB600BDF086 /* InfoPlist.strings */ = {
420 | isa = PBXVariantGroup;
421 | children = (
422 | D779146A16D23BB600BDF086 /* en */,
423 | );
424 | name = InfoPlist.strings;
425 | sourceTree = "";
426 | };
427 | D779148716D23BB700BDF086 /* InfoPlist.strings */ = {
428 | isa = PBXVariantGroup;
429 | children = (
430 | D779148816D23BB700BDF086 /* en */,
431 | );
432 | name = InfoPlist.strings;
433 | sourceTree = "";
434 | };
435 | /* End PBXVariantGroup section */
436 |
437 | /* Begin XCBuildConfiguration section */
438 | D779148D16D23BB700BDF086 /* Debug */ = {
439 | isa = XCBuildConfiguration;
440 | buildSettings = {
441 | ALWAYS_SEARCH_USER_PATHS = NO;
442 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
443 | CLANG_CXX_LIBRARY = "libc++";
444 | CLANG_WARN_CONSTANT_CONVERSION = YES;
445 | CLANG_WARN_EMPTY_BODY = YES;
446 | CLANG_WARN_ENUM_CONVERSION = YES;
447 | CLANG_WARN_INT_CONVERSION = YES;
448 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
449 | CODE_SIGN_IDENTITY = "";
450 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
451 | COPY_PHASE_STRIP = NO;
452 | GCC_C_LANGUAGE_STANDARD = gnu99;
453 | GCC_DYNAMIC_NO_PIC = NO;
454 | GCC_OPTIMIZATION_LEVEL = 0;
455 | GCC_PREPROCESSOR_DEFINITIONS = (
456 | "DEBUG=1",
457 | "$(inherited)",
458 | );
459 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
460 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
461 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
462 | GCC_WARN_UNUSED_VARIABLE = YES;
463 | IPHONEOS_DEPLOYMENT_TARGET = 4.3;
464 | ONLY_ACTIVE_ARCH = YES;
465 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
466 | SDKROOT = iphoneos;
467 | };
468 | name = Debug;
469 | };
470 | D779148E16D23BB700BDF086 /* Release */ = {
471 | isa = XCBuildConfiguration;
472 | buildSettings = {
473 | ALWAYS_SEARCH_USER_PATHS = NO;
474 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
475 | CLANG_CXX_LIBRARY = "libc++";
476 | CLANG_WARN_CONSTANT_CONVERSION = YES;
477 | CLANG_WARN_EMPTY_BODY = YES;
478 | CLANG_WARN_ENUM_CONVERSION = YES;
479 | CLANG_WARN_INT_CONVERSION = YES;
480 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
481 | CODE_SIGN_IDENTITY = "";
482 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
483 | COPY_PHASE_STRIP = YES;
484 | GCC_C_LANGUAGE_STANDARD = gnu99;
485 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
486 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
487 | GCC_WARN_UNUSED_VARIABLE = YES;
488 | IPHONEOS_DEPLOYMENT_TARGET = 4.3;
489 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
490 | SDKROOT = iphoneos;
491 | VALIDATE_PRODUCT = YES;
492 | };
493 | name = Release;
494 | };
495 | D779149016D23BB700BDF086 /* Debug */ = {
496 | isa = XCBuildConfiguration;
497 | buildSettings = {
498 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
499 | GCC_PREFIX_HEADER = "LTUpdate Demo/LTUpdate Demo-Prefix.pch";
500 | INFOPLIST_FILE = "LTUpdate Demo/LTUpdate Demo-Info.plist";
501 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
502 | PRODUCT_NAME = "$(TARGET_NAME)";
503 | TARGETED_DEVICE_FAMILY = "1,2";
504 | WRAPPER_EXTENSION = app;
505 | };
506 | name = Debug;
507 | };
508 | D779149116D23BB700BDF086 /* Release */ = {
509 | isa = XCBuildConfiguration;
510 | buildSettings = {
511 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
512 | GCC_PREFIX_HEADER = "LTUpdate Demo/LTUpdate Demo-Prefix.pch";
513 | INFOPLIST_FILE = "LTUpdate Demo/LTUpdate Demo-Info.plist";
514 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
515 | PRODUCT_NAME = "$(TARGET_NAME)";
516 | TARGETED_DEVICE_FAMILY = "1,2";
517 | WRAPPER_EXTENSION = app;
518 | };
519 | name = Release;
520 | };
521 | D779149316D23BB700BDF086 /* Debug */ = {
522 | isa = XCBuildConfiguration;
523 | buildSettings = {
524 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LTUpdate Demo.app/LTUpdate Demo";
525 | FRAMEWORK_SEARCH_PATHS = (
526 | "\"$(SDKROOT)/Developer/Library/Frameworks\"",
527 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
528 | );
529 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
530 | GCC_PREFIX_HEADER = "LTUpdate Demo/LTUpdate Demo-Prefix.pch";
531 | INFOPLIST_FILE = "LTUpdate DemoTests/LTUpdate DemoTests-Info.plist";
532 | PRODUCT_NAME = "$(TARGET_NAME)";
533 | TEST_HOST = "$(BUNDLE_LOADER)";
534 | WRAPPER_EXTENSION = octest;
535 | };
536 | name = Debug;
537 | };
538 | D779149416D23BB700BDF086 /* Release */ = {
539 | isa = XCBuildConfiguration;
540 | buildSettings = {
541 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LTUpdate Demo.app/LTUpdate Demo";
542 | FRAMEWORK_SEARCH_PATHS = (
543 | "\"$(SDKROOT)/Developer/Library/Frameworks\"",
544 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
545 | );
546 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
547 | GCC_PREFIX_HEADER = "LTUpdate Demo/LTUpdate Demo-Prefix.pch";
548 | INFOPLIST_FILE = "LTUpdate DemoTests/LTUpdate DemoTests-Info.plist";
549 | PRODUCT_NAME = "$(TARGET_NAME)";
550 | TEST_HOST = "$(BUNDLE_LOADER)";
551 | WRAPPER_EXTENSION = octest;
552 | };
553 | name = Release;
554 | };
555 | /* End XCBuildConfiguration section */
556 |
557 | /* Begin XCConfigurationList section */
558 | D779145816D23BB600BDF086 /* Build configuration list for PBXProject "LTUpdate Demo" */ = {
559 | isa = XCConfigurationList;
560 | buildConfigurations = (
561 | D779148D16D23BB700BDF086 /* Debug */,
562 | D779148E16D23BB700BDF086 /* Release */,
563 | );
564 | defaultConfigurationIsVisible = 0;
565 | defaultConfigurationName = Release;
566 | };
567 | D779148F16D23BB700BDF086 /* Build configuration list for PBXNativeTarget "LTUpdate Demo" */ = {
568 | isa = XCConfigurationList;
569 | buildConfigurations = (
570 | D779149016D23BB700BDF086 /* Debug */,
571 | D779149116D23BB700BDF086 /* Release */,
572 | );
573 | defaultConfigurationIsVisible = 0;
574 | defaultConfigurationName = Release;
575 | };
576 | D779149216D23BB700BDF086 /* Build configuration list for PBXNativeTarget "LTUpdate DemoTests" */ = {
577 | isa = XCConfigurationList;
578 | buildConfigurations = (
579 | D779149316D23BB700BDF086 /* Debug */,
580 | D779149416D23BB700BDF086 /* Release */,
581 | );
582 | defaultConfigurationIsVisible = 0;
583 | defaultConfigurationName = Release;
584 | };
585 | /* End XCConfigurationList section */
586 | };
587 | rootObject = D779145516D23BB600BDF086 /* Project object */;
588 | }
589 |
--------------------------------------------------------------------------------