iPad version

This commit is contained in:
Abel Fokkinga 2013-02-21 17:08:51 +01:00
parent eae41e0e3f
commit 797a47e84a
65 changed files with 3422 additions and 516 deletions

View File

@ -13,9 +13,14 @@
B506EC6D15EBF67500566A27 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B506EC6B15EBF67500566A27 /* InfoPlist.strings */; };
B506EC6F15EBF67500566A27 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B506EC6E15EBF67500566A27 /* main.m */; };
B506EC7315EBF67500566A27 /* EspagramAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B506EC7215EBF67500566A27 /* EspagramAppDelegate.m */; };
B506EC7615EBF67500566A27 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B506EC7415EBF67500566A27 /* MainStoryboard.storyboard */; };
B506EC7615EBF67500566A27 /* EspagramiPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B506EC7415EBF67500566A27 /* EspagramiPhone.storyboard */; };
B506EC7915EBF67500566A27 /* EspagramViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B506EC7815EBF67500566A27 /* EspagramViewController.m */; };
B506ECA515EE898700566A27 /* SpanishConjugator.m in Sources */ = {isa = PBXBuildFile; fileRef = B506ECA415EE898700566A27 /* SpanishConjugator.m */; };
B51112BA16D2538C0070DB4D /* EspagramiPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B51112B916D2538C0070DB4D /* EspagramiPad.storyboard */; };
B51112BC16D2540B0070DB4D /* espagram72.png in Resources */ = {isa = PBXBuildFile; fileRef = B51112BB16D2540B0070DB4D /* espagram72.png */; };
B51112BE16D254750070DB4D /* espagram144.png in Resources */ = {isa = PBXBuildFile; fileRef = B51112BD16D254750070DB4D /* espagram144.png */; };
B51112C216D27DCE0070DB4D /* RotatableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B51112C016D27DCE0070DB4D /* RotatableViewController.m */; };
B51112C416D28EF90070DB4D /* espagram.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B51112C316D28EF90070DB4D /* espagram.jpg */; };
B512F63B164BEC6000DA031E /* EspagramTestViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B512F63A164BEC6000DA031E /* EspagramTestViewController.m */; };
B512F658164D1A0C00DA031E /* EspagramConjugationTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B512F657164D1A0C00DA031E /* EspagramConjugationTableViewController.m */; };
B512F670164D60DB00DA031E /* EspagramMainTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B512F66F164D60DB00DA031E /* EspagramMainTableViewController.m */; };
@ -58,11 +63,22 @@
B581EA08169B351A005D9936 /* TestResult+Create.m in Sources */ = {isa = PBXBuildFile; fileRef = B581EA07169B351A005D9936 /* TestResult+Create.m */; };
B581EA0E169DA304005D9936 /* EspagramTypingTestViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B581EA0D169DA304005D9936 /* EspagramTypingTestViewController.m */; };
B581EA10169DD28F005D9936 /* tabbar_typing.png in Resources */ = {isa = PBXBuildFile; fileRef = B581EA0F169DD28F005D9936 /* tabbar_typing.png */; };
B58BB0EB16D635A30032E6EB /* Default Espagram database EN.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = B58BB0EA16D635A30032E6EB /* Default Espagram database EN.sqlite */; };
B58BB0ED16D635B00032E6EB /* Default Espagram database NL.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = B58BB0EC16D635B00032E6EB /* Default Espagram database NL.sqlite */; };
B58BB0EF16D636D30032E6EB /* Default Espagram database DE.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = B58BB0EE16D636D30032E6EB /* Default Espagram database DE.sqlite */; };
B5A8BB191651A64300C1CC00 /* CoreDataTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B5A8BB181651A3E700C1CC00 /* CoreDataTableViewController.m */; };
B5B3F92D165972EF00E26A40 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B5B3F92F165972EF00E26A40 /* Localizable.strings */; };
B5B3F93516602C7C00E26A40 /* Verb.m in Sources */ = {isa = PBXBuildFile; fileRef = B5B3F93416602C7B00E26A40 /* Verb.m */; };
B5B3F93816602C7D00E26A40 /* TestResult.m in Sources */ = {isa = PBXBuildFile; fileRef = B5B3F93716602C7C00E26A40 /* TestResult.m */; };
B5B3F93B16602C7E00E26A40 /* Lesson.m in Sources */ = {isa = PBXBuildFile; fileRef = B5B3F93A16602C7E00E26A40 /* Lesson.m */; };
B5CE337116D22E47004B34DB /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5CE337016D22E47004B34DB /* CFNetwork.framework */; };
B5CE337316D22E51004B34DB /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5CE337216D22E51004B34DB /* SystemConfiguration.framework */; };
B5CE337516D22E5A004B34DB /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5CE337416D22E5A004B34DB /* StoreKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
B5CE339616D22ECF004B34DB /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = B5CE337716D22ECF004B34DB /* .gitignore */; };
B5CE339716D22ECF004B34DB /* Appirater.m in Sources */ = {isa = PBXBuildFile; fileRef = B5CE337916D22ECF004B34DB /* Appirater.m */; };
B5CE339816D22ECF004B34DB /* Appirater.podspec in Resources */ = {isa = PBXBuildFile; fileRef = B5CE337A16D22ECF004B34DB /* Appirater.podspec */; };
B5CE339916D22ECF004B34DB /* AppiraterLocalizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B5CE337C16D22ECF004B34DB /* AppiraterLocalizable.strings */; };
B5CE339A16D22ECF004B34DB /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = B5CE338F16D22ECF004B34DB /* README.md */; };
B5EC6CED1656F1960030C27F /* Verb+Create.m in Sources */ = {isa = PBXBuildFile; fileRef = B5EC6CEC1656F1960030C27F /* Verb+Create.m */; };
B5EFD392162CB18000C6E2EB /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5EFD391162CB18000C6E2EB /* Default-568h@2x.png */; };
/* End PBXBuildFile section */
@ -89,11 +105,18 @@
B506EC7015EBF67500566A27 /* Espagram-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Espagram-Prefix.pch"; sourceTree = "<group>"; };
B506EC7115EBF67500566A27 /* EspagramAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EspagramAppDelegate.h; sourceTree = "<group>"; };
B506EC7215EBF67500566A27 /* EspagramAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EspagramAppDelegate.m; sourceTree = "<group>"; };
B506EC7515EBF67500566A27 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = "<group>"; };
B506EC7515EBF67500566A27 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/EspagramiPhone.storyboard; sourceTree = "<group>"; };
B506EC7715EBF67500566A27 /* EspagramViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EspagramViewController.h; sourceTree = "<group>"; };
B506EC7815EBF67500566A27 /* EspagramViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EspagramViewController.m; sourceTree = "<group>"; };
B506ECA315EE898700566A27 /* SpanishConjugator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpanishConjugator.h; sourceTree = "<group>"; };
B506ECA415EE898700566A27 /* SpanishConjugator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpanishConjugator.m; sourceTree = "<group>"; };
B51112B916D2538C0070DB4D /* EspagramiPad.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = EspagramiPad.storyboard; sourceTree = "<group>"; };
B51112BB16D2540B0070DB4D /* espagram72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = espagram72.png; sourceTree = "<group>"; };
B51112BD16D254750070DB4D /* espagram144.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = espagram144.png; sourceTree = "<group>"; };
B51112BF16D27DCE0070DB4D /* RotatableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RotatableViewController.h; path = "../../../../Downloads/Psychologist-2/Psychologist/RotatableViewController.h"; sourceTree = "<group>"; };
B51112C016D27DCE0070DB4D /* RotatableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RotatableViewController.m; path = "../../../../Downloads/Psychologist-2/Psychologist/RotatableViewController.m"; sourceTree = "<group>"; };
B51112C116D27DCE0070DB4D /* SplitViewBarButtonItemPresenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SplitViewBarButtonItemPresenter.h; path = "../../../../Downloads/Psychologist-2/Psychologist/SplitViewBarButtonItemPresenter.h"; sourceTree = "<group>"; };
B51112C316D28EF90070DB4D /* espagram.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = espagram.jpg; sourceTree = "<group>"; };
B512F639164BEC6000DA031E /* EspagramTestViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EspagramTestViewController.h; sourceTree = "<group>"; };
B512F63A164BEC6000DA031E /* EspagramTestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EspagramTestViewController.m; sourceTree = "<group>"; };
B512F656164D1A0C00DA031E /* EspagramConjugationTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EspagramConjugationTableViewController.h; sourceTree = "<group>"; };
@ -149,6 +172,11 @@
B581EA0C169DA303005D9936 /* EspagramTypingTestViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EspagramTypingTestViewController.h; sourceTree = "<group>"; };
B581EA0D169DA304005D9936 /* EspagramTypingTestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EspagramTypingTestViewController.m; sourceTree = "<group>"; };
B581EA0F169DD28F005D9936 /* tabbar_typing.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tabbar_typing.png; sourceTree = "<group>"; };
B58BB0E516D57DE70032E6EB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
B58BB0EA16D635A30032E6EB /* Default Espagram database EN.sqlite */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "Default Espagram database EN.sqlite"; sourceTree = "<group>"; };
B58BB0EC16D635B00032E6EB /* Default Espagram database NL.sqlite */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "Default Espagram database NL.sqlite"; sourceTree = "<group>"; };
B58BB0EE16D636D30032E6EB /* Default Espagram database DE.sqlite */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "Default Espagram database DE.sqlite"; sourceTree = "<group>"; };
B58BB0F016D666200032E6EB /* Espagram.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Espagram.entitlements; sourceTree = "<group>"; };
B58F57661635D27E00CED51B /* Conjugator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Conjugator.h; sourceTree = "<group>"; };
B58F576D16387BE600CED51B /* NSMutableArray_Shuffling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSMutableArray_Shuffling.h; path = Espagram/NSMutableArray_Shuffling.h; sourceTree = "<group>"; };
B5A8BB171651A3E700C1CC00 /* CoreDataTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreDataTableViewController.h; sourceTree = "<group>"; };
@ -164,6 +192,39 @@
B5B3F93716602C7C00E26A40 /* TestResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestResult.m; sourceTree = "<group>"; };
B5B3F93916602C7E00E26A40 /* Lesson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lesson.h; sourceTree = "<group>"; };
B5B3F93A16602C7E00E26A40 /* Lesson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Lesson.m; sourceTree = "<group>"; };
B5CE337016D22E47004B34DB /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
B5CE337216D22E51004B34DB /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
B5CE337416D22E5A004B34DB /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
B5CE337716D22ECF004B34DB /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
B5CE337816D22ECF004B34DB /* Appirater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Appirater.h; sourceTree = "<group>"; };
B5CE337916D22ECF004B34DB /* Appirater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Appirater.m; sourceTree = "<group>"; };
B5CE337A16D22ECF004B34DB /* Appirater.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Appirater.podspec; sourceTree = "<group>"; };
B5CE337B16D22ECF004B34DB /* AppiraterDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppiraterDelegate.h; sourceTree = "<group>"; };
B5CE337D16D22ECF004B34DB /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE337E16D22ECF004B34DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE337F16D22ECF004B34DB /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338016D22ECF004B34DB /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338116D22ECF004B34DB /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338216D22ECF004B34DB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338316D22ECF004B34DB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338416D22ECF004B34DB /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338516D22ECF004B34DB /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338616D22ECF004B34DB /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338716D22ECF004B34DB /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338816D22ECF004B34DB /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338916D22ECF004B34DB /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338A16D22ECF004B34DB /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338B16D22ECF004B34DB /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338C16D22ECF004B34DB /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338D16D22ECF004B34DB /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338E16D22ECF004B34DB /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE338F16D22ECF004B34DB /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
B5CE339016D22ECF004B34DB /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE339116D22ECF004B34DB /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE339216D22ECF004B34DB /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE339316D22ECF004B34DB /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/AppiraterLocalizable.strings; sourceTree = "<group>"; };
B5CE339416D22ECF004B34DB /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/AppiraterLocalizable.strings"; sourceTree = "<group>"; };
B5CE339516D22ECF004B34DB /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/AppiraterLocalizable.strings"; sourceTree = "<group>"; };
B5E2A282168602CD00874448 /* EspagramLessonTesting.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EspagramLessonTesting.h; sourceTree = "<group>"; };
B5EC6CEB1656F1960030C27F /* Verb+Create.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Verb+Create.h"; sourceTree = "<group>"; };
B5EC6CEC1656F1960030C27F /* Verb+Create.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Verb+Create.m"; sourceTree = "<group>"; };
@ -175,6 +236,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B5CE337516D22E5A004B34DB /* StoreKit.framework in Frameworks */,
B5CE337316D22E51004B34DB /* SystemConfiguration.framework in Frameworks */,
B5CE337116D22E47004B34DB /* CFNetwork.framework in Frameworks */,
B51F8E4816519FE00033B614 /* CoreData.framework in Frameworks */,
B506EC6315EBF67500566A27 /* UIKit.framework in Frameworks */,
B506EC6515EBF67500566A27 /* Foundation.framework in Frameworks */,
@ -188,6 +252,16 @@
B506EC5315EBF67500566A27 = {
isa = PBXGroup;
children = (
B58BB0EE16D636D30032E6EB /* Default Espagram database DE.sqlite */,
B58BB0EC16D635B00032E6EB /* Default Espagram database NL.sqlite */,
B58BB0EA16D635A30032E6EB /* Default Espagram database EN.sqlite */,
B51112BD16D254750070DB4D /* espagram144.png */,
B51112BB16D2540B0070DB4D /* espagram72.png */,
B51112C316D28EF90070DB4D /* espagram.jpg */,
B5CE337616D22ECF004B34DB /* appirater-master */,
B5CE337416D22E5A004B34DB /* StoreKit.framework */,
B5CE337216D22E51004B34DB /* SystemConfiguration.framework */,
B5CE337016D22E47004B34DB /* CFNetwork.framework */,
B545E000167BA01700DFBF11 /* espagram117.png */,
B545DFFE167BA00300DFBF11 /* espagram57.png */,
B545DFFB167A5F2800DFBF11 /* Default Espagram database.sqlite */,
@ -223,13 +297,18 @@
B506EC6815EBF67500566A27 /* Espagram */ = {
isa = PBXGroup;
children = (
B58BB0F016D666200032E6EB /* Espagram.entitlements */,
B5E2A282168602CD00874448 /* EspagramLessonTesting.h */,
B54CFB741652E03600C0823D /* EspagramNewLessonViewController.h */,
B54CFB751652E03600C0823D /* EspagramNewLessonViewController.m */,
B5A8BB171651A3E700C1CC00 /* CoreDataTableViewController.h */,
B5A8BB181651A3E700C1CC00 /* CoreDataTableViewController.m */,
B506EC7115EBF67500566A27 /* EspagramAppDelegate.h */,
B506EC7415EBF67500566A27 /* MainStoryboard.storyboard */,
B506EC7415EBF67500566A27 /* EspagramiPhone.storyboard */,
B51112B916D2538C0070DB4D /* EspagramiPad.storyboard */,
B51112BF16D27DCE0070DB4D /* RotatableViewController.h */,
B51112C016D27DCE0070DB4D /* RotatableViewController.m */,
B51112C116D27DCE0070DB4D /* SplitViewBarButtonItemPresenter.h */,
B581EA0C169DA303005D9936 /* EspagramTypingTestViewController.h */,
B581EA0D169DA304005D9936 /* EspagramTypingTestViewController.m */,
B56DE15E165426B800D85DD3 /* EspagramAddWordToLessonViewController.h */,
@ -317,6 +396,20 @@
name = Images;
sourceTree = "<group>";
};
B5CE337616D22ECF004B34DB /* appirater-master */ = {
isa = PBXGroup;
children = (
B5CE337716D22ECF004B34DB /* .gitignore */,
B5CE337816D22ECF004B34DB /* Appirater.h */,
B5CE337916D22ECF004B34DB /* Appirater.m */,
B5CE337A16D22ECF004B34DB /* Appirater.podspec */,
B5CE337B16D22ECF004B34DB /* AppiraterDelegate.h */,
B5CE337C16D22ECF004B34DB /* AppiraterLocalizable.strings */,
B5CE338F16D22ECF004B34DB /* README.md */,
);
path = "appirater-master";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -345,7 +438,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = Espagram;
LastUpgradeCheck = 0450;
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = "Abel Fokkinga";
};
buildConfigurationList = B506EC5815EBF67500566A27 /* Build configuration list for PBXProject "Espagram" */;
@ -357,6 +450,26 @@
nl,
es,
pt,
ca,
cs,
da,
de,
el,
fi,
fr,
he,
hu,
it,
ja,
ko,
nb,
pl,
ru,
sk,
sv,
tr,
"zh-Hans",
"zh-Hant",
);
mainGroup = B506EC5315EBF67500566A27;
productRefGroup = B506EC5F15EBF67500566A27 /* Products */;
@ -374,7 +487,7 @@
buildActionMask = 2147483647;
files = (
B506EC6D15EBF67500566A27 /* InfoPlist.strings in Resources */,
B506EC7615EBF67500566A27 /* MainStoryboard.storyboard in Resources */,
B506EC7615EBF67500566A27 /* EspagramiPhone.storyboard in Resources */,
B5EFD392162CB18000C6E2EB /* Default-568h@2x.png in Resources */,
B51F8E4416519D440033B614 /* iPhoneIcon_Small.png in Resources */,
B51F8E4616519D490033B614 /* iPhoneIcon_Big.png in Resources */,
@ -403,6 +516,17 @@
B581EA03168E3037005D9936 /* check_box.png in Resources */,
B581EA05168E3099005D9936 /* check_box-1.png in Resources */,
B581EA10169DD28F005D9936 /* tabbar_typing.png in Resources */,
B5CE339616D22ECF004B34DB /* .gitignore in Resources */,
B5CE339816D22ECF004B34DB /* Appirater.podspec in Resources */,
B5CE339916D22ECF004B34DB /* AppiraterLocalizable.strings in Resources */,
B5CE339A16D22ECF004B34DB /* README.md in Resources */,
B51112BA16D2538C0070DB4D /* EspagramiPad.storyboard in Resources */,
B51112BC16D2540B0070DB4D /* espagram72.png in Resources */,
B51112BE16D254750070DB4D /* espagram144.png in Resources */,
B51112C416D28EF90070DB4D /* espagram.jpg in Resources */,
B58BB0EB16D635A30032E6EB /* Default Espagram database EN.sqlite in Resources */,
B58BB0ED16D635B00032E6EB /* Default Espagram database NL.sqlite in Resources */,
B58BB0EF16D636D30032E6EB /* Default Espagram database DE.sqlite in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -437,6 +561,8 @@
B5B3F93B16602C7E00E26A40 /* Lesson.m in Sources */,
B581EA08169B351A005D9936 /* TestResult+Create.m in Sources */,
B581EA0E169DA304005D9936 /* EspagramTypingTestViewController.m in Sources */,
B5CE339716D22ECF004B34DB /* Appirater.m in Sources */,
B51112C216D27DCE0070DB4D /* RotatableViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -451,12 +577,12 @@
name = InfoPlist.strings;
sourceTree = "<group>";
};
B506EC7415EBF67500566A27 /* MainStoryboard.storyboard */ = {
B506EC7415EBF67500566A27 /* EspagramiPhone.storyboard */ = {
isa = PBXVariantGroup;
children = (
B506EC7515EBF67500566A27 /* en */,
);
name = MainStoryboard.storyboard;
name = EspagramiPhone.storyboard;
sourceTree = "<group>";
};
B5B3F92F165972EF00E26A40 /* Localizable.strings */ = {
@ -466,10 +592,42 @@
B5B3F930165972F600E26A40 /* en */,
B5B3F931165AC79200E26A40 /* es */,
B5B3F932165AD45400E26A40 /* pt */,
B58BB0E516D57DE70032E6EB /* de */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
B5CE337C16D22ECF004B34DB /* AppiraterLocalizable.strings */ = {
isa = PBXVariantGroup;
children = (
B5CE337D16D22ECF004B34DB /* ca */,
B5CE337E16D22ECF004B34DB /* cs */,
B5CE337F16D22ECF004B34DB /* da */,
B5CE338016D22ECF004B34DB /* de */,
B5CE338116D22ECF004B34DB /* el */,
B5CE338216D22ECF004B34DB /* en */,
B5CE338316D22ECF004B34DB /* es */,
B5CE338416D22ECF004B34DB /* fi */,
B5CE338516D22ECF004B34DB /* fr */,
B5CE338616D22ECF004B34DB /* he */,
B5CE338716D22ECF004B34DB /* hu */,
B5CE338816D22ECF004B34DB /* it */,
B5CE338916D22ECF004B34DB /* ja */,
B5CE338A16D22ECF004B34DB /* ko */,
B5CE338B16D22ECF004B34DB /* nb */,
B5CE338C16D22ECF004B34DB /* nl */,
B5CE338D16D22ECF004B34DB /* pl */,
B5CE338E16D22ECF004B34DB /* pt */,
B5CE339016D22ECF004B34DB /* ru */,
B5CE339116D22ECF004B34DB /* sk */,
B5CE339216D22ECF004B34DB /* sv */,
B5CE339316D22ECF004B34DB /* tr */,
B5CE339416D22ECF004B34DB /* zh-Hans */,
B5CE339516D22ECF004B34DB /* zh-Hant */,
);
name = AppiraterLocalizable.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@ -480,8 +638,11 @@
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
@ -495,7 +656,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
SDKROOT = iphoneos;
};
name = Debug;
@ -507,15 +668,18 @@
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
@ -525,16 +689,19 @@
B506EC7D15EBF67500566A27 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Abel Fokkinga (P764G4C7BB)";
CODE_SIGN_ENTITLEMENTS = Espagram/Espagram.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Espagram/Espagram-Prefix.pch";
INFOPLIST_FILE = "Espagram/Espagram-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "D1DA148D-74FB-4B18-82EB-1E4B06A36830";
TARGETED_DEVICE_FAMILY = 1;
"PROVISIONING_PROFILE[sdk=*]" = "B9D6A7A6-94DA-4D3D-AD3E-2204789BC56E";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
};
name = Debug;
@ -542,14 +709,17 @@
B506EC7E15EBF67500566A27 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Distribution: Abel Fokkinga";
CODE_SIGN_ENTITLEMENTS = Espagram/Espagram.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Espagram/Espagram-Prefix.pch";
INFOPLIST_FILE = "Espagram/Espagram-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "B9D6A7A6-94DA-4D3D-AD3E-2204789BC56E";
TARGETED_DEVICE_FAMILY = 1;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=*]" = "B9D6A7A6-94DA-4D3D-AD3E-2204789BC56E";
TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
};
name = Release;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0450"
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -18,6 +18,8 @@
<array>
<string>espagram57.png</string>
<string>espagram117.png</string>
<string>espagram72.png</string>
<string>espagram144.png</string>
</array>
</dict>
</dict>
@ -37,11 +39,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.2</string>
<string>1.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.2</string>
<string>1.3</string>
<key>LSApplicationCategoryType</key>
<string></string>
<key>LSRequiresIPhoneOS</key>
@ -49,7 +51,9 @@
<key>NSHumanReadableCopyright</key>
<string>Abel Fokkinga</string>
<key>UIMainStoryboardFile</key>
<string>MainStoryboard</string>
<string>EspagramiPhone</string>
<key>UIMainStoryboardFile~ipad</key>
<string>EspagramiPad</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
@ -68,5 +72,12 @@
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.fokkinga.abel.Espagram</string>
</array>
</dict>
</plist>

View File

@ -15,6 +15,8 @@
- (void) cancelAddingWord;
- (NSString *) searchWordMeaning:(NSString *)word;
@end
@interface EspagramAddWordToLessonViewController : UIViewController

View File

@ -26,6 +26,11 @@
[self resignFirstResponder];
}
- (IBAction)verbEntered {
self.meaningInputText.text = [self.dataSource searchWordMeaning:self.wordInputText.text];
}
- (IBAction)addButtonPressed:(id)sender {
[self.dataSource addWord: self.wordInputText.text withMeaning:self.meaningInputText.text];
}

View File

@ -7,6 +7,7 @@
//
#import "EspagramAppDelegate.h"
#import "Appirater.h"
@implementation EspagramAppDelegate
@ -104,6 +105,12 @@
// Override point for customization after application launch.
[self customizeAppearance];
return YES;
// App rater
[Appirater setAppId:@"587567966"];
[Appirater appLaunched:YES];
}
- (void)applicationWillResignActive:(UIApplication *)application
@ -121,6 +128,9 @@
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
// App rater
[Appirater appEnteredForeground:YES];
}
- (void)applicationDidBecomeActive:(UIApplication *)application

View File

@ -10,11 +10,12 @@
#import "CoreDataTableViewController.h"
#import "Conjugator.h"
#import "EspagramNewLessonViewController.h"
#import "EspagramAddWordToLessonViewController.h"
#import "Lesson.h"
#import "Tense.h"
@interface EspagramLessonViewController : CoreDataTableViewController <EspagramNewLessonDelegate>
@interface EspagramLessonViewController : CoreDataTableViewController <EspagramAddWordToLessonViewControllerDelegate,EspagramNewLessonDelegate>
@property (nonatomic, strong) UIManagedDocument * lessonsDatabase;
@property (nonatomic, strong) Lesson * lesson;

View File

@ -16,22 +16,26 @@
@interface EspagramLessonViewController ()
@property UITabBarController * tabBarController;
@property (strong,nonatomic) UIPopoverController *myPopover;
@end
@implementation EspagramLessonViewController
@implementation EspagramLessonViewController
@synthesize lessonsDatabase = _lessonsDatabase;
@synthesize lesson = _lesson;
@synthesize conjugator = _conjugator;
@synthesize tense = _tense;
@synthesize tabBarController;
@synthesize tabBarController = _tabBarController;
@synthesize myPopover = _myPopover;
- (IBAction)AddButtonPressed:(id)sender {
NSLog(@"Selected lesson %@", self.lesson.title);
[self performSegueWithIdentifier:@"Add A Word To Lesson" sender:self];
}
// Only reached on iPhone
- (void) addWord:(NSString *)word withMeaning:(NSString *)meaning{
if ( word ) {
NSLog(@"Selected lesson %@", self.lesson.title);
@ -51,6 +55,16 @@
}
- (NSString *) searchWordMeaning:(NSString *)word
{
if ( word ) {
Verb * v= [Verb searchWordMeaning:word usingLessonLanguage:self.lesson];
return v.meaning;
}
return nil;
};
// Only reached on iPhone
- (void) cancelAddingWord{
[[self parentViewController] dismissViewControllerAnimated:TRUE completion:^{ NSLog(@"Adding a word cancelled");
}];
@ -62,10 +76,15 @@
- (void) addLesson:(NSString*)title withDescription:(NSString*) subTitle {
NSLog(@"Need to dismiss modal view controller");
[[self presentedViewController] dismissViewControllerAnimated:TRUE completion:^{
NSLog(@"View controller dismissed");
}];
if ( self.myPopover ) {
// On iPad. Dismiss the pop over
[[self myPopover] dismissPopoverAnimated:TRUE];
self.myPopover = nil;
} else {
// On iPhone
[[self parentViewController] dismissViewControllerAnimated:TRUE completion:^{
}];
}
NSLog(@"database %@, context %@", self.lessonsDatabase,[self.lessonsDatabase managedObjectContext]);
@ -75,10 +94,15 @@
}
- (void) cancelLesson{
NSLog(@"Cancel pressed, need to dismiss modal view controller");
[[self presentedViewController] dismissViewControllerAnimated:TRUE completion:^{
NSLog(@"View controller dismissed");
}];
if ( self.myPopover ) {
// On iPad. Dismiss the pop over
[[self myPopover] dismissPopoverAnimated:TRUE];
self.myPopover = nil;
} else {
// On iPhone
[[self parentViewController] dismissViewControllerAnimated:TRUE completion:^{
}];
}
}
@ -148,7 +172,13 @@ didSelectViewController:(UIViewController *)viewController {
[super viewWillAppear:animated];
self.title = NSLocalizedString(@"Lessons title",@"Lessons title");
if ( self.splitViewController) {
// self.title = NSLocalizedString([@"TENSE_" stringByAppendingString:self.tense.tense], nil);
self.title = [self.tense getTenseInLanguage:[self.conjugator description]];
} else {
NSLocalizedString(@"Lessons title",@"Lessons title");
}
if (!self.lessonsDatabase) { // We'll create a default database if none is set
@ -306,6 +336,11 @@ didSelectViewController:(UIViewController *)viewController {
if ( [segue.identifier isEqualToString:@"Add new Lesson"]){
NSLog(@"Preparing for segue Add new Lesson");
[segue.destinationViewController setDataSource:self];
if ( self.splitViewController ) {
// On iPad, we want to store the pointer to the popOver
self.myPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
}
}
if ( [segue.identifier isEqualToString:@"Add A Word To Lesson"]) {
@ -316,7 +351,8 @@ didSelectViewController:(UIViewController *)viewController {
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:@"Testing Tab Bar" sender:[self.tableView cellForRowAtIndexPath:indexPath]];
[self performSegueWithIdentifier:@"Testing Tab Bar" sender:[self.tableView cellForRowAtIndexPath:indexPath]];
// [self performSegueWithIdentifier:@"Testing" sender:[self.tableView cellForRowAtIndexPath:indexPath]];
}

View File

@ -8,7 +8,7 @@
#import <UIKit/UIKit.h>
@interface EspagramMainTableViewController : UITableViewController
@interface EspagramMainTableViewController : UITableViewController <UISplitViewControllerDelegate>
@property (weak, nonatomic) IBOutlet UIBarButtonItem *aboutButton;

View File

@ -10,6 +10,7 @@
#import "SpanishConjugator.h"
#import "EspagramTestViewController.h"
#import "EspagramLessonViewController.h"
#import "SplitViewBarButtonItemPresenter.h"
@interface EspagramMainTableViewController ()
@property (nonatomic, strong) NSString *language, *displayTitle;
@ -35,6 +36,46 @@
}
- (void)awakeFromNib // always try to be the split view's delegate
{
[super awakeFromNib];
self.splitViewController.delegate = self;
}
- (id <SplitViewBarButtonItemPresenter>)splitViewBarButtonItemPresenter
{
id detailVC = [self.splitViewController.viewControllers lastObject];
if (![detailVC conformsToProtocol:@protocol(SplitViewBarButtonItemPresenter)]) {
detailVC = nil;
}
return detailVC;
}
- (BOOL)splitViewController:(UISplitViewController *)svc
shouldHideViewController:(UIViewController *)vc
inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
//return [self splitViewBarButtonItemPresenter] ? UIInterfaceOrientationIsPortrait(orientation) : NO;
}
- (void)splitViewController:(UISplitViewController *)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem *)barButtonItem
forPopoverController:(UIPopoverController *)pc
{
barButtonItem.title = self.title;
[self splitViewBarButtonItemPresenter].splitViewBarButtonItem = barButtonItem;
}
- (void)splitViewController:(UISplitViewController *)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
[self splitViewBarButtonItemPresenter].splitViewBarButtonItem = nil;
}
# pragma mark - Espagram setters and getters
- (id <Conjugator>) getLanguage {
@ -136,10 +177,21 @@
NSLog(@"DB url: %@", storeURL.path);
if (![fileManager fileExistsAtPath:storeURL.path]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Default Espagram database" ofType:@"sqlite"];
//NSString *defaultStorePath = [[[NSBundle mainBundle] resourcePath]
// stringByAppendingPathComponent:@"Default Espagram database"];
NSString *languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
if ([languageCode isEqualToString:@"en"]) {
NSLog(@"Default DB is EN");
defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Default Espagram database EN" ofType:@"sqlite"];
}else if ([languageCode isEqualToString:@"nl"]) {
NSLog(@"Default DB is NL");
defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Default Espagram database NL" ofType:@"sqlite"];
}else if ([languageCode isEqualToString:@"de"]) {
NSLog(@"Default DB is DE");
defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Default Espagram database DE" ofType:@"sqlite"];
}
if ( [fileManager fileExistsAtPath:defaultStorePath]) {

View File

@ -21,6 +21,8 @@
@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UIButton *addButton;
@property (weak, nonatomic) IBOutlet UIButton *cancelButton;

View File

@ -15,6 +15,7 @@
@implementation EspagramNewLessonViewController
@synthesize nameLabel = _nameLabel;
@synthesize titleLabel = _titleLabel;
@synthesize descriptionLabel = _descriptionLabel;
@synthesize addButton = _addButton;
@synthesize lessonDescriptionTextInput = _lessonDescriptionTextInput;
@ -39,11 +40,12 @@
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.titleLabel.text = NSLocalizedString( @"Add a new lesson",@"Add a new lesson (long description)");
self.nameLabel.text = NSLocalizedString(@"Lesson title", @"Lesson title when adding a new lesson");
self.descriptionLabel.text = NSLocalizedString(@"Description", @"Lesson description when adding a new lesson");

View File

@ -22,6 +22,8 @@
@property (weak, nonatomic) IBOutlet UILabel *verbPersonLabel;
@property (weak, nonatomic) IBOutlet UILabel *verbTestTenseLabel;
@property (weak, nonatomic) IBOutlet UIButton *answer1Button;
@property (weak, nonatomic) IBOutlet UIButton *answer2Button;
@ -32,5 +34,8 @@
@property (weak, nonatomic) IBOutlet UIButton *nextButton;
@property (weak, nonatomic) IBOutlet UIProgressView *testProgressIndicator;
@property (weak, nonatomic) IBOutlet UILabel *testStatusLabel;
@end

View File

@ -25,6 +25,7 @@
@synthesize testedVerbLabel = _testedVerbLabel;
@synthesize verbMeaningLable = _testedVerbLable;
@synthesize verbPersonLabel = _verbPersonLabel;
@synthesize verbTestTenseLabel = _verbTestTenseLabel;
@synthesize answer1Button = _answer1Button;
@synthesize answer2Button = _answer2Button;
@synthesize answer3Button = _answer3Button;
@ -34,6 +35,8 @@
@synthesize currentVerb = _currentVerb;
@synthesize correctAnswersInCurrentSet = _correctAnswersInCurrentSet;
@synthesize wrongAnswersInCurrentSet = _wrongAnswersInCurrentSet;
@synthesize testProgressIndicator = _testProgressIndicator;
@synthesize testStatusLabel = _testStatusLabel;
- (NSMutableArray *)testSet{
@ -46,6 +49,18 @@
return _testSet;
};
- (void) updateTestProgress
{
if ( self.testSet.count == 0 ) {
self.testProgressIndicator.progress = 0;
} else {
self.testProgressIndicator.progress = self.correctAnswersInCurrentSet * 1.0 / (self.testSet.count + self.correctAnswersInCurrentSet);
}
self.testStatusLabel.text = [NSString stringWithFormat:@"%@: %d %@: %d %@: %d",NSLocalizedString(@"Correct",@"Number of correct answers"),self.correctAnswersInCurrentSet,
NSLocalizedString(@"Error",@"Number of incorrect answers"),self.wrongAnswersInCurrentSet,
NSLocalizedString(@"Total",@"Number of total conjugations in test"),self.testSet.count+self.correctAnswersInCurrentSet];
}
- (IBAction)answered:(UIButton *)sender {
@ -75,9 +90,31 @@
return lastObject;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(@"user pressed Continue");
}
else {
NSLog(@"user pressed Cancel");
}
}
- (IBAction)nextButtonPressed:(id)sender {
[self.testSet removeLastObject];
if ( self.testSet.count == 1 &&
self.correctAnswersInCurrentSet > 0 &&
self.currentVerb.failed == false) {
//Create UIAlertView alert
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(@"Congratulations",@"Congratulations title")
message:NSLocalizedString(@"You succesfully completed this lesson!",@"Lesson completed succesfully message")
delegate:self
cancelButtonTitle:NSLocalizedString(@"Continue",@"Quit lesson completed completed alert message") otherButtonTitles: nil];
// Show alert
[alert show];
}
[self nextVerb];
}
@ -124,22 +161,26 @@
// Add test result
if ( self.currentVerb) {
[TestResult addTestableVerbResult:self.currentVerb withTestType:@"Multiple Choice"];
if ( self.currentVerb.failed) {
// Last test failed.. so we won't remove it
// instead we shuffle the test set.
self.currentVerb.failed = false;
[self.testSet shuffle];
// increase wrongly answered counter
self.wrongAnswersInCurrentSet += 1;
} else {
// Last verb answered correctly
[self.testSet removeLastObject];
// increase correct answered counter
self.correctAnswersInCurrentSet += 1;
}
}
if ( self.currentVerb && self.currentVerb.failed) {
// Last test failed.. so we won't remove it
// instead we shuffle the test set.
[self.testSet shuffle];
// increase wrongly answered counter
self.wrongAnswersInCurrentSet += 1;
} {
// Last verb answered correctly
[self.testSet lastObject];
// increase wrongly answered counter
self.correctAnswersInCurrentSet += 1;
}
// Update progress indicator
[self updateTestProgress];
self.currentVerb = self.testSet.lastObject;
@ -185,6 +226,8 @@
self.title = NSLocalizedString(@"Multiple Choice",@"Multiple Choice test");
self.verbTestTenseLabel.text = [self.lesson getLocalizedTense];
self.nextButton.titleLabel.text = NSLocalizedString(@"Next", @"Next button in the testing screen to continue to the next verb");
[self.nextButton setTitle:NSLocalizedString(@"Next", @"Next button in the testing screen to continue to the next verb") forState:UIControlStateNormal];

View File

@ -23,6 +23,8 @@
@property (weak, nonatomic) IBOutlet UILabel *verbPersonLabel;
@property (weak, nonatomic) IBOutlet UILabel *verbTestTenseLabel;
@property (weak, nonatomic) IBOutlet UIButton *nextButton;
@property (weak, nonatomic) IBOutlet UIButton *checkAnswerButton;
@ -31,4 +33,8 @@
@property (weak, nonatomic) IBOutlet UITextField *verbAnswerTextField;
@property (weak, nonatomic) IBOutlet UIProgressView *testProgressIndicator;
@property (weak, nonatomic) IBOutlet UILabel *testStatusLabel;
@end

View File

@ -33,7 +33,9 @@
@synthesize currentVerb = _currentVerb;
@synthesize correctAnswersInCurrentSet = _correctAnswersInCurrentSet;
@synthesize wrongAnswersInCurrentSet = _wrongAnswersInCurrentSet;
@synthesize verbTestTenseLabel = _verbTestTenseLabel;
@synthesize testProgressIndicator = _testProgressIndicator;
@synthesize testStatusLabel = _testStatusLabel;
- (NSMutableArray *)testSet{
// Check if there are any verbs in the set
@ -45,6 +47,29 @@
return _testSet;
};
- (void) updateTestProgress
{
if ( self.testSet.count == 0 ) {
self.testProgressIndicator.progress = 0;
} else {
self.testProgressIndicator.progress = self.correctAnswersInCurrentSet * 1.0 / (self.testSet.count + self.correctAnswersInCurrentSet);
}
self.testStatusLabel.text = [NSString stringWithFormat:@"%@: %d %@: %d %@: %d",NSLocalizedString(@"Correct",@"Number of correct answers"),self.correctAnswersInCurrentSet,
NSLocalizedString(@"Error",@"Number of incorrect answers"),self.wrongAnswersInCurrentSet,
NSLocalizedString(@"Total",@"Number of total conjugations in test"),self.testSet.count+self.correctAnswersInCurrentSet];
}
- (void)setLesson:(Lesson *)lesson{
if ( _lesson != lesson){
// Clear current test set
self.testSet = nil;
// set Tense label
self.verbTestTenseLabel.text = [self.lesson getLocalizedTense];
_lesson = lesson;
}
}
- (void) setUIButtonTitle:(UIButton *)button withText:(NSString *) titleString inColour:(UIColor *) colour forState:(UIControlState)controlState
{
NSAttributedString *title;
@ -72,6 +97,7 @@
- (void) checkAnswer:(NSString *) answer {
NSString * correctAnswer = [self.lesson.getConjugationEngine conjugateVerb:self.currentVerb.verb.verb inPerson:self.currentVerb.person andTense:[self.lesson getTenseAsTense]];
@ -93,25 +119,29 @@
// Add test result
if ( self.currentVerb) {
[TestResult addTestableVerbResult:self.currentVerb withTestType:@"Typing"];
}
if ( self.currentVerb.failed) {
// Last test failed.. so we won't remove it
// instead we shuffle the test set.
self.currentVerb.failed = false;
[self.testSet shuffle];
// increase wrongly answered counter
self.wrongAnswersInCurrentSet += 1;
} else {
// Last verb answered correctly
[self.testSet removeLastObject];
// increase correct answered counter
self.correctAnswersInCurrentSet += 1;
}
if ( self.currentVerb && self.currentVerb.failed) {
// Last test failed.. so we won't remove it
// instead we shuffle the test set.
[self.testSet shuffle];
// increase wrongly answered counter
self.wrongAnswersInCurrentSet += 1;
} {
// Last verb answered correctly
[self.testSet lastObject];
// increase wrongly answered counter
self.correctAnswersInCurrentSet += 1;
}
self.currentVerb = self.testSet.lastObject;
// Update progress indicator
[self updateTestProgress];
if ( self.currentVerb) {
@ -121,6 +151,7 @@
NSLog(@"Correct answer: %@", correctAnswer);
// Set display label to verb to test
[self setUILabelTitle:self.testedVerbLabel withText:self.currentVerb.verb.verb inColour:[UIColor blackColor] andSize:30];
@ -152,8 +183,22 @@
}
- (IBAction)nextButtonPressed:(id)sender {
[self.testSet removeLastObject];
if ( self.testSet.count == 1 &&
self.correctAnswersInCurrentSet > 0 &&
self.currentVerb.failed == false) {
//Create UIAlertView alert
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(@"Congratulations",@"Congratulations title")
message:NSLocalizedString(@"You succesfully completed this lesson!",@"Lesson completed succesfully message")
delegate:self
cancelButtonTitle:NSLocalizedString(@"Continue",@"Quit lesson completed completed alert message") otherButtonTitles: nil];
// Show alert
[alert show];
}
[self nextVerb];
self.verbAnswerTextField.text = @"";
}
@ -174,7 +219,9 @@
[super viewWillAppear:animated];
self.title = NSLocalizedString(@"Typing",@"Typing Test");
self.verbTestTenseLabel.text = [self.lesson getLocalizedTense];
self.nextButton.titleLabel.text = NSLocalizedString(@"Next", @"Next button in the testing screen to continue to the next verb");
[self.nextButton setTitle:NSLocalizedString(@"Next", @"Next button in the testing screen to continue to the next verb") forState:UIControlStateNormal];

View File

@ -11,12 +11,14 @@
#import "Verb+Create.h"
@interface EspagramWordsInLessonViewController ()
@property (strong,nonatomic) UIPopoverController *myPopover;
@end
@implementation EspagramWordsInLessonViewController
@synthesize lesson = _lesson;
@synthesize delegate = _delegate;
@synthesize myPopover = _myPopover;
- (IBAction)AddButtonPressed:(id)sender {
@ -27,14 +29,46 @@
if ( word ) {
[Verb addVerb:word andMeaning:meaning toLesson:self.lesson];
}
[[self parentViewController] dismissViewControllerAnimated:TRUE completion:^{
NSLog(@"Word added");
if ( self.myPopover ) {
// On iPad. Dismiss the pop over
[[self myPopover] dismissPopoverAnimated:TRUE];
self.myPopover = nil;
} else {
// On iPhone
[[self parentViewController] dismissViewControllerAnimated:TRUE completion:^{
}];
}
if ( self.lesson.verbs.count > 0 && self.tabBarController ) {
// Words in lesson, enable tabs
NSArray *tabItems = self.tabBarController.tabBar.items;
for (UIBarItem *tabItem in tabItems)
{
[tabItem setEnabled:true];
}
}
}
- (NSString *) searchWordMeaning:(NSString *)word
{
if ( word ) {
Verb * v= [Verb searchWordMeaning:word usingLessonLanguage:self.lesson];
return v.meaning;
}
return nil;
};
- (void) cancelAddingWord{
[[self parentViewController] dismissViewControllerAnimated:TRUE completion:^{ NSLog(@"Adding a word cancelled");
}];
if ( self.myPopover ) {
// On iPad, Dismiss the pop over
[[self myPopover] dismissPopoverAnimated:TRUE];
self.myPopover = nil;
} else {
// On iPhone
[[self parentViewController] dismissViewControllerAnimated:TRUE completion:^{ NSLog(@"Adding a word cancelled");
}];
}
}
- (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
@ -46,7 +80,6 @@
request.predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:[NSPredicate predicateWithFormat:@"lesson.title = %@", self.lesson.title], [NSPredicate predicateWithFormat:@"lesson.tense = %@", self.lesson.tense], [NSPredicate predicateWithFormat:@"lesson.conjugator = %@", self.lesson.conjugator],nil]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.lesson.managedObjectContext
sectionNameKeyPath:nil
@ -100,6 +133,11 @@
return les;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects] + 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
@ -107,9 +145,15 @@
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
Verb * verb = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = verb.verb;
cell.detailTextLabel.text = verb.meaning;
if ( indexPath.row + 1 > [[[self.fetchedResultsController sections] objectAtIndex:indexPath.section] numberOfObjects]){
cell.textLabel.text = NSLocalizedString(@"Add new...",@"Add a new verb (short description)");
cell.detailTextLabel.text = NSLocalizedString(@"Add a new verb",@"Add a new verb (long description)");
} else {
Verb * verb = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = verb.verb;
cell.detailTextLabel.text = verb.meaning;
}
return cell;
}
@ -117,8 +161,14 @@
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ( [segue.identifier isEqualToString:@"Add A Word To Lesson"]) {
[segue.destinationViewController setDataSource:self];
if ( self.splitViewController ) {
// On iPad, we want to store the pointer to the popOver
self.myPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
}
}
if ( [segue.identifier isEqualToString:@"Conjugate"]) {
@ -127,6 +177,16 @@
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"selected verb %@",[[[self.tableView cellForRowAtIndexPath:indexPath] textLabel] text ]);
if ( [[[[self.tableView cellForRowAtIndexPath:indexPath] textLabel] text] isEqualToString:NSLocalizedString(@"Add new...",@"Add a new verb (short description)")] ) {
[self performSegueWithIdentifier:@"Add A Word To Lesson" sender:self];
} else {
[self performSegueWithIdentifier:@"Conjugate" sender:indexPath];
}
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
@ -136,7 +196,6 @@
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
@ -171,9 +230,4 @@
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:@"Conjugate" sender:indexPath];
}
@end

File diff suppressed because it is too large Load Diff

View File

@ -18,4 +18,6 @@
- (NSString *) getTenseName;
- (NSString *) getLocalizedTense;
@end

View File

@ -34,4 +34,9 @@
return [tense getTenseInLanguage:self.conjugator];
}
- (NSString *) getLocalizedTense;
{
return NSLocalizedString([@"TENSE_" stringByAppendingString:self.tense], nil);
}
@end

View File

@ -30,28 +30,49 @@
if ( !_text) {
if ( [self.tense isEqualToString:@"SIMPLE_PRESENT"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Presente",@"Simple present",@"Onvoltooid tegenwoordige tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
initWithObjects:@"Presente de Indicativo",@"Simple present",@"Tegenwoordige tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"PRESENT_SUBJUNCTIVE"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Presente de Subjuntivo",@"Present subjunctive",@"Aanvoegende wijs",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"SIMPLE_PAST"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Indefinido",@"Simple past",@"Verleden tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
initWithObjects:@"Pretérito Indefinido",@"Simple past",@"Verleden tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"IMPERFECT"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Imperfecto",@"Imperfect",@"Onvoltooid verleden tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"IMPERFECT_SUBJUNCTIVE"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Imperfecto de Subjuntivo",@"Imperfect subjunctive",@"Onvoltooid aanvoegende wijs",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"FUTURE"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Futuro",@"Future",@"Toekomstige tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"PRESENT_PERFECT"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Perfecto",@"Present perfect",@"Pretérito perfecto",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
initWithObjects:@"Pretérito Perfecto",@"Present perfect",@"Voltooid tegenwoordige tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"PERFECT_SUBJUNCTIVE"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Perfecto de Subjuntivo",@"Present perfect subjunctive",@"Voltooid aanvoegende wijs",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"PAST_PERFECT"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Pluscuamperfecto",@"Past perfect",@"Pretérito pluscuamperfecto",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
initWithObjects:@"Pluscuamperfecto",@"Past perfect",@"Voltooid verleden tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"PAST_PERFECT_SUBJUNCTIVE"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Pluscuamperfecto Subjuntivo",@"Past perfect subjunctive",@"Voltooid verleden aanvoegende wijs",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"FUTURE_PERFECT"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Futuro perfecto",@"Future perfect",@"Pretérito pluscuamperfecto",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
initWithObjects:@"Futuro perfecto",@"Future perfect",@"Voltooid tegenwoordige toekomende tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"CONDITIONAL"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Condicional",@"Conditional",@"Voorwaardelijke wijs",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
initWithObjects:@"Condicional",@"Conditional",@"Onvoltooid verleden toekomende tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"CONDITIONAL_PERFECT"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Condicional Perfecto",@"Conditional Perfect",@"Voltooid verleden toekomende tijd",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];
if ( [self.tense isEqualToString:@"GERUND"])
_text = [[NSDictionary alloc] initWithObjects:[[NSArray alloc]
initWithObjects:@"Gerundio",@"Gerund",@"Tegenwoordig deelwoord",nil] forKeys:[[NSArray alloc] initWithObjects:@"Spanish",@"English",@"Dutch", nil]];

View File

@ -12,5 +12,6 @@
@interface Verb (Create)
+ (void) addVerb:(NSString *)newVerb andMeaning:(NSString *)meaning toLesson:(Lesson *)lesson;
+ (Verb *) searchWordMeaning:(NSString *)verb usingLessonLanguage:(Lesson *)lesson;
@end

View File

@ -60,4 +60,27 @@
[[lesson managedObjectContext] save:nil];
};
+ (Verb *) searchWordMeaning:(NSString *)verb usingLessonLanguage:(Lesson *)lesson
{
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Verb"];
// Where clause
request.predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:[NSPredicate predicateWithFormat:@"verb = %@", verb],
[NSPredicate predicateWithFormat:@"meaning != nil AND meaning !=''"],
[NSPredicate predicateWithFormat:@"lesson.conjugator = %@", lesson.conjugator],nil]];
NSError *error = nil;
NSArray *verbs = [[lesson managedObjectContext] executeFetchRequest:request error:&error];
if ( verbs && verbs.count > 0 ){
return [verbs lastObject];
}
return nil;
};
@end

Binary file not shown.

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="2844" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="oPi-YX-voa">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="oPi-YX-voa">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1930"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="2083"/>
</dependencies>
<scenes>
<!--Espagram Main Table View Controller - Espagram-->
@ -104,8 +104,8 @@
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</label>
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="TENSE_PRESENT_PERFECT_SUBJUNCTIVE" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ICg-tz-BYA">
<rect key="frame" x="10" y="24" width="260" height="18"/>
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="TENSE_PERFECT_SUBJUNCTIVE" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ICg-tz-BYA">
<rect key="frame" x="10" y="24" width="225" height="18"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.50196078431372548" green="0.50196078431372548" blue="0.50196078431372548" alpha="1" colorSpace="calibratedRGB"/>
@ -635,7 +635,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="gHf-EZ-b4O" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="979" y="-1015"/>
<point key="canvasLocation" x="961" y="-959"/>
</scene>
<!--Espagram Test View Controller - Multiple Choice-->
<scene sceneID="lbJ-Av-XmM">
@ -660,8 +660,8 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" hasAttributedTitle="YES" id="GwC-Bf-HXP">
<rect key="frame" x="20" y="109" width="280" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="frame" x="20" y="109" width="280" height="37"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal">
<attributedString key="attributedTitle">
@ -679,8 +679,8 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" hasAttributedTitle="YES" id="SQD-lH-VYW">
<rect key="frame" x="20" y="160" width="280" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="frame" x="20" y="153" width="280" height="37"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal">
<attributedString key="attributedTitle">
@ -697,8 +697,8 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" hasAttributedTitle="YES" id="wjU-6t-8IW">
<rect key="frame" x="20" y="211" width="280" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="frame" x="20" y="197" width="280" height="37"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal">
<attributedString key="attributedTitle">
@ -715,8 +715,8 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" hasAttributedTitle="YES" id="oF7-P6-yi9">
<rect key="frame" x="20" y="262" width="280" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<rect key="frame" x="20" y="241" width="280" height="37"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal">
<attributedString key="attributedTitle">
@ -733,7 +733,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="9jU-k2-QRJ">
<rect key="frame" x="20" y="313" width="280" height="44"/>
<rect key="frame" x="20" y="285" width="280" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<state key="normal" title="Next">
@ -749,7 +749,7 @@
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="vIa-Z9-dQK">
<rect key="frame" x="20" y="74" width="280" height="32"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
<fragment content="Person">
<attributes>
@ -775,6 +775,11 @@
</attributedString>
<nil key="highlightedColor"/>
</label>
<progressView opaque="NO" contentMode="scaleToFill" progress="0.5" id="fMh-We-UbK">
<rect key="frame" x="20" y="336" width="280" height="9"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="progressTintColor" red="0.0" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
</progressView>
</subviews>
<color key="backgroundColor" red="0.92037779090000005" green="0.84682043169999999" blue="0.62681043489999999" alpha="1" colorSpace="calibratedRGB"/>
</view>
@ -786,6 +791,7 @@
<outlet property="answer3Button" destination="wjU-6t-8IW" id="XJK-0e-Vd6"/>
<outlet property="answer4Button" destination="oF7-P6-yi9" id="tLQ-6O-sUs"/>
<outlet property="nextButton" destination="9jU-k2-QRJ" id="AXC-IX-fmp"/>
<outlet property="testProgressIndicator" destination="fMh-We-UbK" id="f1y-Ji-Z5h"/>
<outlet property="testedVerbLabel" destination="j9Z-GN-xos" id="bip-se-GgG"/>
<outlet property="verbMeaningLable" destination="PQt-9o-rOa" id="Ph8-yR-0kJ"/>
<outlet property="verbPersonLabel" destination="vIa-Z9-dQK" id="iEb-LC-wQb"/>
@ -794,7 +800,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="3Kf-gx-xfq" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="979" y="-293"/>
<point key="canvasLocation" x="990" y="-311"/>
</scene>
<!--Tab Bar Controller-->
<scene sceneID="lCz-RG-hnO">
@ -861,7 +867,7 @@
<navigationItem key="navigationItem" title="Words" id="Fdg-5d-vck">
<barButtonItem key="rightBarButtonItem" systemItem="add" id="G74-V1-sDK">
<connections>
<action selector="AddButtonPressed:" destination="x6z-xh-dlG" id="jhx-3C-Shi"/>
<action selector="AddButtonPressed:" destination="x6z-xh-dlG" id="qUD-IE-TjZ"/>
</connections>
</barButtonItem>
</navigationItem>
@ -897,7 +903,7 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="tHV-ju-jYt">
<rect key="frame" x="20" y="309" width="285" height="44"/>
<rect key="frame" x="20" y="284" width="285" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<state key="normal" title="Next">
@ -967,7 +973,7 @@
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="oky-Ng-qk8">
<rect key="frame" x="20" y="258" width="285" height="44"/>
<rect key="frame" x="20" y="233" width="285" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" title="Answer">
@ -1056,6 +1062,11 @@
<action selector="addAccentedCharacter:" destination="QXI-XP-mxq" eventType="touchUpInside" id="XmZ-lR-J0G"/>
</connections>
</button>
<progressView opaque="NO" contentMode="scaleToFill" progress="0.5" id="aIY-Iq-FoL">
<rect key="frame" x="20" y="343" width="285" height="9"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="progressTintColor" red="0.0" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
</progressView>
</subviews>
<color key="backgroundColor" red="0.92037779090000005" green="0.84682043169999999" blue="0.62681043489999999" alpha="1" colorSpace="calibratedRGB"/>
</view>
@ -1064,6 +1075,7 @@
<outlet property="checkAnswerButton" destination="b2m-pe-KH3" id="0pW-Ve-813"/>
<outlet property="nextButton" destination="tHV-ju-jYt" id="8t1-fM-Vz5"/>
<outlet property="showAnswerButton" destination="oky-Ng-qk8" id="9md-2e-34Z"/>
<outlet property="testProgressIndicator" destination="aIY-Iq-FoL" id="WmR-IG-GKI"/>
<outlet property="testedVerbLabel" destination="e4v-C6-jif" id="TDn-20-RqB"/>
<outlet property="verbAnswerTextField" destination="6Qr-xM-8Dq" id="yLu-M9-ntI"/>
<outlet property="verbMeaningLable" destination="h2R-hV-w1C" id="oVD-2J-PhT"/>
@ -1141,8 +1153,8 @@
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<connections>
<action selector="editingDidEnd" destination="jQ9-yg-o3d" eventType="editingDidEnd" id="hfX-ck-gqI"/>
<action selector="editingDidEnd" destination="jQ9-yg-o3d" eventType="editingDidEndOnExit" id="ock-u2-SwF"/>
<action selector="verbEntered" destination="jQ9-yg-o3d" eventType="editingDidEnd" id="Omh-Ps-Oee"/>
</connections>
</textField>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Meaning" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6vS-Fn-ecI">
@ -1233,85 +1245,6 @@
<image name="tabbar_list.png" width="21" height="21"/>
<image name="tabbar_typing.png" width="21" height="21"/>
</resources>
<classes>
<class className="CoreDataTableViewController" superclassName="UITableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/CoreDataTableViewController.h"/>
</class>
<class className="EspagramAddWordToLessonViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramAddWordToLessonViewController.h"/>
<relationships>
<relationship kind="outlet" name="addButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="cancelButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="meaningInputText" candidateClass="UITextField"/>
<relationship kind="outlet" name="meaningLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="wordInputText" candidateClass="UITextField"/>
<relationship kind="outlet" name="wordLabel" candidateClass="UILabel"/>
</relationships>
</class>
<class className="EspagramConjugationTableViewController" superclassName="UITableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramConjugationTableViewController.h"/>
<relationships>
<relationship kind="outlet" name="verb" candidateClass="Verb"/>
</relationships>
</class>
<class className="EspagramLessonViewController" superclassName="CoreDataTableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramLessonViewController.h"/>
</class>
<class className="EspagramMainTableViewController" superclassName="UITableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramMainTableViewController.h"/>
<relationships>
<relationship kind="outlet" name="aboutButton" candidateClass="UIBarButtonItem"/>
</relationships>
</class>
<class className="EspagramNewLessonViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramNewLessonViewController.h"/>
<relationships>
<relationship kind="action" name="cancelButtonPressed:"/>
<relationship kind="action" name="editingDidEnd:"/>
<relationship kind="outlet" name="addButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="cancelButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="descriptionLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="lessonDescriptionTextInput" candidateClass="UITextField"/>
<relationship kind="outlet" name="lessonNameTextInput" candidateClass="UITextField"/>
<relationship kind="outlet" name="nameLabel" candidateClass="UILabel"/>
</relationships>
</class>
<class className="EspagramTestViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramTestViewController.h"/>
<relationships>
<relationship kind="outlet" name="answer1Button" candidateClass="UIButton"/>
<relationship kind="outlet" name="answer2Button" candidateClass="UIButton"/>
<relationship kind="outlet" name="answer3Button" candidateClass="UIButton"/>
<relationship kind="outlet" name="answer4Button" candidateClass="UIButton"/>
<relationship kind="outlet" name="nextButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="testedVerbLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="verbMeaningLable" candidateClass="UILabel"/>
<relationship kind="outlet" name="verbPersonLabel" candidateClass="UILabel"/>
</relationships>
</class>
<class className="EspagramTypingTestViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramTypingTestViewController.h"/>
<relationships>
<relationship kind="action" name="addAccentedCharacter:" candidateClass="UIButton"/>
<relationship kind="action" name="answerEntered:"/>
<relationship kind="action" name="nextButtonPressed:"/>
<relationship kind="action" name="showCorrectAnswerButtonPressed:"/>
<relationship kind="outlet" name="checkAnswerButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="nextButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="showAnswerButton" candidateClass="UIButton"/>
<relationship kind="outlet" name="testedVerbLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="verbAnswerTextField" candidateClass="UITextField"/>
<relationship kind="outlet" name="verbMeaningLable" candidateClass="UILabel"/>
<relationship kind="outlet" name="verbPersonLabel" candidateClass="UILabel"/>
</relationships>
</class>
<class className="EspagramWordsInLessonViewController" superclassName="CoreDataTableViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EspagramWordsInLessonViewController.h"/>
</class>
<class className="Verb" superclassName="NSManagedObject">
<source key="sourceIdentifier" type="project" relativePath="./Classes/Verb.h"/>
</class>
</classes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>

View File

@ -54,6 +54,33 @@
/* Show correct answer button */
"Answer" = "Antwoord?";
/* Add a new verb (short description) */
"Add new..." = "Nieuw...";
/* Add a new verb (long description) */
"Add a new verb" = "Voeg een nieuw werkwoord toe";
/* Add a new lesson (long description) */
"Add a new lesson" = "Nieuwe les toevoegen";
/* Number of correct answers */
"Correct" = "Correct";
/* Number of incorrect answers */
"Error" = "Fout";
/* Number of total conjugations in test */
"Total" = "Totaal";
/* Congratulations title */
"Congratulations" = "Gefeliciteerd";
/* Lesson completed succesfully message */
"You succesfully completed this lesson!" = "Je hebt deze les succesvol afgerond!";
/* Quit lesson completed completed alert message */
"Continue" = "Verder";
/* Simple present tense description */
"TENSE_SIMPLE_PRESENT" = "Tegenwoordige tijd";
@ -91,7 +118,7 @@
"TENSE_PRESENT_SUBJUNCTIVE" = "Aanvoegende wijs";
/* Present subjunctive tense description */
"TENSE_PRESENT_PERFECT_SUBJUNCTIVE" = "Voltooid aanvoegende wijs";
"TENSE_PERFECT_SUBJUNCTIVE" = "Voltooid aanvoegende wijs";
/* Present perfect subjunctive tense description */
"TENSE_IMPERFECT_SUBJUNCTIVE" = "Onvoltooid aanvoegende wijs";

2
appirater-master/.gitignore vendored Executable file
View File

@ -0,0 +1,2 @@
.DS_Store

240
appirater-master/Appirater.h Executable file
View File

@ -0,0 +1,240 @@
/*
This file is part of Appirater.
Copyright (c) 2012, Arash Payan
All rights reserved.
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:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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.
*/
/*
* Appirater.h
* appirater
*
* Created by Arash Payan on 9/5/09.
* http://arashpayan.com
* Copyright 2012 Arash Payan. All rights reserved.
*/
#import <Foundation/Foundation.h>
#import "AppiraterDelegate.h"
#import <StoreKit/StoreKit.h>
extern NSString *const kAppiraterFirstUseDate;
extern NSString *const kAppiraterUseCount;
extern NSString *const kAppiraterSignificantEventCount;
extern NSString *const kAppiraterCurrentVersion;
extern NSString *const kAppiraterRatedCurrentVersion;
extern NSString *const kAppiraterDeclinedToRate;
extern NSString *const kAppiraterReminderRequestDate;
/*
Your localized app's name.
*/
#define APPIRATER_LOCALIZED_APP_NAME [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"]
/*
Your app's name.
*/
#define APPIRATER_APP_NAME APPIRATER_LOCALIZED_APP_NAME ? APPIRATER_LOCALIZED_APP_NAME : [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]
/*
This is the message your users will see once they've passed the day+launches
threshold.
*/
#define APPIRATER_LOCALIZED_MESSAGE NSLocalizedStringFromTable(@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", @"AppiraterLocalizable", nil)
#define APPIRATER_MESSAGE [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE, APPIRATER_APP_NAME]
/*
This is the title of the message alert that users will see.
*/
#define APPIRATER_LOCALIZED_MESSAGE_TITLE NSLocalizedStringFromTable(@"Rate %@", @"AppiraterLocalizable", nil)
#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE_TITLE, APPIRATER_APP_NAME]
/*
The text of the button that rejects reviewing the app.
*/
#define APPIRATER_CANCEL_BUTTON NSLocalizedStringFromTable(@"No, Thanks", @"AppiraterLocalizable", nil)
/*
Text of button that will send user to app review page.
*/
#define APPIRATER_LOCALIZED_RATE_BUTTON NSLocalizedStringFromTable(@"Rate %@", @"AppiraterLocalizable", nil)
#define APPIRATER_RATE_BUTTON [NSString stringWithFormat:APPIRATER_LOCALIZED_RATE_BUTTON, APPIRATER_APP_NAME]
/*
Text for button to remind the user to review later.
*/
#define APPIRATER_RATE_LATER NSLocalizedStringFromTable(@"Remind me later", @"AppiraterLocalizable", nil)
@interface Appirater : NSObject <UIAlertViewDelegate, SKStoreProductViewControllerDelegate> {
UIAlertView *ratingAlert;
}
@property(nonatomic, strong) UIAlertView *ratingAlert;
#if __has_feature(objc_arc_weak)
@property(nonatomic, weak) NSObject <AppiraterDelegate> *delegate;
#else
@property(nonatomic, unsafe_unretained) NSObject <AppiraterDelegate> *delegate;
#endif
/*
Tells Appirater that the app has launched, and on devices that do NOT
support multitasking, the 'uses' count will be incremented. You should
call this method at the end of your application delegate's
application:didFinishLaunchingWithOptions: method.
If the app has been used enough to be rated (and enough significant events),
you can suppress the rating alert
by passing NO for canPromptForRating. The rating alert will simply be postponed
until it is called again with YES for canPromptForRating. The rating alert
can also be triggered by appEnteredForeground: and userDidSignificantEvent:
(as long as you pass YES for canPromptForRating in those methods).
*/
+ (void)appLaunched:(BOOL)canPromptForRating;
/*
Tells Appirater that the app was brought to the foreground on multitasking
devices. You should call this method from the application delegate's
applicationWillEnterForeground: method.
If the app has been used enough to be rated (and enough significant events),
you can suppress the rating alert
by passing NO for canPromptForRating. The rating alert will simply be postponed
until it is called again with YES for canPromptForRating. The rating alert
can also be triggered by appLaunched: and userDidSignificantEvent:
(as long as you pass YES for canPromptForRating in those methods).
*/
+ (void)appEnteredForeground:(BOOL)canPromptForRating;
/*
Tells Appirater that the user performed a significant event. A significant
event is whatever you want it to be. If you're app is used to make VoIP
calls, then you might want to call this method whenever the user places
a call. If it's a game, you might want to call this whenever the user
beats a level boss.
If the user has performed enough significant events and used the app enough,
you can suppress the rating alert by passing NO for canPromptForRating. The
rating alert will simply be postponed until it is called again with YES for
canPromptForRating. The rating alert can also be triggered by appLaunched:
and appEnteredForeground: (as long as you pass YES for canPromptForRating
in those methods).
*/
+ (void)userDidSignificantEvent:(BOOL)canPromptForRating;
/*
Tells Appirater to open the App Store page where the user can specify a
rating for the app. Also records the fact that this has happened, so the
user won't be prompted again to rate the app.
The only case where you should call this directly is if your app has an
explicit "Rate this app" command somewhere. In all other cases, don't worry
about calling this -- instead, just call the other functions listed above,
and let Appirater handle the bookkeeping of deciding when to ask the user
whether to rate the app.
*/
+ (void)rateApp;
/*
Tells Appirater to immediately close any open rating modals (e.g. StoreKit rating VCs).
*/
+ (void)closeModal;
@end
@interface Appirater(Configuration)
/*
Set your Apple generated software id here.
*/
+ (void) setAppId:(NSString*)appId;
/*
Users will need to have the same version of your app installed for this many
days before they will be prompted to rate it.
*/
+ (void) setDaysUntilPrompt:(double)value;
/*
An example of a 'use' would be if the user launched the app. Bringing the app
into the foreground (on devices that support it) would also be considered
a 'use'. You tell Appirater about these events using the two methods:
[Appirater appLaunched:]
[Appirater appEnteredForeground:]
Users need to 'use' the same version of the app this many times before
before they will be prompted to rate it.
*/
+ (void) setUsesUntilPrompt:(NSInteger)value;
/*
A significant event can be anything you want to be in your app. In a
telephone app, a significant event might be placing or receiving a call.
In a game, it might be beating a level or a boss. This is just another
layer of filtering that can be used to make sure that only the most
loyal of your users are being prompted to rate you on the app store.
If you leave this at a value of -1, then this won't be a criterion
used for rating. To tell Appirater that the user has performed
a significant event, call the method:
[Appirater userDidSignificantEvent:];
*/
+ (void) setSignificantEventsUntilPrompt:(NSInteger)value;
/*
Once the rating alert is presented to the user, they might select
'Remind me later'. This value specifies how long (in days) Appirater
will wait before reminding them.
*/
+ (void) setTimeBeforeReminding:(double)value;
/*
'YES' will show the Appirater alert everytime. Useful for testing how your message
looks and making sure the link to your app's review page works.
*/
+ (void) setDebug:(BOOL)debug;
/*
Set the delegate if you want to know when Appirater does something
*/
+ (void)setDelegate:(id<AppiraterDelegate>)delegate;
/*
Set whether or not Appirater uses animation (currently respected when pushing modal StoreKit rating VCs).
*/
+ (void)setUsesAnimation:(BOOL)animation;
@end
@interface Appirater(Deprecated)
/*
DEPRECATED: While still functional, it's better to use
appLaunched:(BOOL)canPromptForRating instead.
Calls [Appirater appLaunched:YES]. See appLaunched: for details of functionality.
*/
+ (void)appLaunched __attribute__((deprecated));
@end

492
appirater-master/Appirater.m Executable file
View File

@ -0,0 +1,492 @@
/*
This file is part of Appirater.
Copyright (c) 2012, Arash Payan
All rights reserved.
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:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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.
*/
/*
* Appirater.m
* appirater
*
* Created by Arash Payan on 9/5/09.
* http://arashpayan.com
* Copyright 2012 Arash Payan. All rights reserved.
*/
#import "Appirater.h"
#import <SystemConfiguration/SCNetworkReachability.h>
#include <netinet/in.h>
#if ! __has_feature(objc_arc)
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
#endif
NSString *const kAppiraterFirstUseDate = @"kAppiraterFirstUseDate";
NSString *const kAppiraterUseCount = @"kAppiraterUseCount";
NSString *const kAppiraterSignificantEventCount = @"kAppiraterSignificantEventCount";
NSString *const kAppiraterCurrentVersion = @"kAppiraterCurrentVersion";
NSString *const kAppiraterRatedCurrentVersion = @"kAppiraterRatedCurrentVersion";
NSString *const kAppiraterDeclinedToRate = @"kAppiraterDeclinedToRate";
NSString *const kAppiraterReminderRequestDate = @"kAppiraterReminderRequestDate";
NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
static NSString *_appId;
static double _daysUntilPrompt = 30;
static NSInteger _usesUntilPrompt = 20;
static NSInteger _significantEventsUntilPrompt = -1;
static double _timeBeforeReminding = 1;
static BOOL _debug = NO;
static id<AppiraterDelegate> _delegate;
static BOOL _usesAnimation = TRUE;
static UIStatusBarStyle _statusBarStyle;
static BOOL _modalOpen = false;
@interface Appirater ()
- (BOOL)connectedToNetwork;
+ (Appirater*)sharedInstance;
- (void)showRatingAlert;
- (BOOL)ratingConditionsHaveBeenMet;
- (void)incrementUseCount;
- (void)hideRatingAlert;
@end
@implementation Appirater
@synthesize ratingAlert;
+ (void) setAppId:(NSString *)appId {
_appId = appId;
}
+ (void) setDaysUntilPrompt:(double)value {
_daysUntilPrompt = value;
}
+ (void) setUsesUntilPrompt:(NSInteger)value {
_usesUntilPrompt = value;
}
+ (void) setSignificantEventsUntilPrompt:(NSInteger)value {
_significantEventsUntilPrompt = value;
}
+ (void) setTimeBeforeReminding:(double)value {
_timeBeforeReminding = value;
}
+ (void) setDebug:(BOOL)debug {
_debug = debug;
}
+ (void)setDelegate:(id<AppiraterDelegate>)delegate{
_delegate = delegate;
}
+ (void)setUsesAnimation:(BOOL)animation {
_usesAnimation = animation;
}
+ (void)setStatusBarStyle:(UIStatusBarStyle)style {
_statusBarStyle = style;
}
+ (void)setModalOpen:(BOOL)open {
_modalOpen = open;
}
- (BOOL)connectedToNetwork {
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
NSLog(@"Error. Could not recover network reachability flags");
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}
+ (Appirater*)sharedInstance {
static Appirater *appirater = nil;
if (appirater == nil)
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
appirater = [[Appirater alloc] init];
appirater.delegate = _delegate;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name:
UIApplicationWillResignActiveNotification object:nil];
});
}
return appirater;
}
- (void)showRatingAlert {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE
message:APPIRATER_MESSAGE
delegate:self
cancelButtonTitle:APPIRATER_CANCEL_BUTTON
otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil];
self.ratingAlert = alertView;
[alertView show];
if(self.delegate && [self.delegate respondsToSelector:@selector(appiraterDidDisplayAlert:)]){
[self.delegate appiraterDidDisplayAlert:self];
}
}
- (BOOL)ratingConditionsHaveBeenMet {
if (_debug)
return YES;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDate *dateOfFirstLaunch = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterFirstUseDate]];
NSTimeInterval timeSinceFirstLaunch = [[NSDate date] timeIntervalSinceDate:dateOfFirstLaunch];
NSTimeInterval timeUntilRate = 60 * 60 * 24 * _daysUntilPrompt;
if (timeSinceFirstLaunch < timeUntilRate)
return NO;
// check if the app has been used enough
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
if (useCount <= _usesUntilPrompt)
return NO;
// check if the user has done enough significant events
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
if (sigEventCount <= _significantEventsUntilPrompt)
return NO;
// has the user previously declined to rate this version of the app?
if ([userDefaults boolForKey:kAppiraterDeclinedToRate])
return NO;
// has the user already rated the app?
if ([userDefaults boolForKey:kAppiraterRatedCurrentVersion])
return NO;
// if the user wanted to be reminded later, has enough time passed?
NSDate *reminderRequestDate = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterReminderRequestDate]];
NSTimeInterval timeSinceReminderRequest = [[NSDate date] timeIntervalSinceDate:reminderRequestDate];
NSTimeInterval timeUntilReminder = 60 * 60 * 24 * _timeBeforeReminding;
if (timeSinceReminderRequest < timeUntilReminder)
return NO;
return YES;
}
- (void)incrementUseCount {
// get the app's version
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
// get the version number that we've been tracking
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
if (trackingVersion == nil)
{
trackingVersion = version;
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
}
if (_debug)
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
if ([trackingVersion isEqualToString:version])
{
// check if the first use date has been set. if not, set it.
NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];
if (timeInterval == 0)
{
timeInterval = [[NSDate date] timeIntervalSince1970];
[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];
}
// increment the use count
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
useCount++;
[userDefaults setInteger:useCount forKey:kAppiraterUseCount];
if (_debug)
NSLog(@"APPIRATER Use count: %d", useCount);
}
else
{
// it's a new version of the app, so restart tracking
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterFirstUseDate];
[userDefaults setInteger:1 forKey:kAppiraterUseCount];
[userDefaults setInteger:0 forKey:kAppiraterSignificantEventCount];
[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];
}
[userDefaults synchronize];
}
- (void)incrementSignificantEventCount {
// get the app's version
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
// get the version number that we've been tracking
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
if (trackingVersion == nil)
{
trackingVersion = version;
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
}
if (_debug)
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
if ([trackingVersion isEqualToString:version])
{
// check if the first use date has been set. if not, set it.
NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate];
if (timeInterval == 0)
{
timeInterval = [[NSDate date] timeIntervalSince1970];
[userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate];
}
// increment the significant event count
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
sigEventCount++;
[userDefaults setInteger:sigEventCount forKey:kAppiraterSignificantEventCount];
if (_debug)
NSLog(@"APPIRATER Significant event count: %d", sigEventCount);
}
else
{
// it's a new version of the app, so restart tracking
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
[userDefaults setDouble:0 forKey:kAppiraterFirstUseDate];
[userDefaults setInteger:0 forKey:kAppiraterUseCount];
[userDefaults setInteger:1 forKey:kAppiraterSignificantEventCount];
[userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
[userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
[userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate];
}
[userDefaults synchronize];
}
- (void)incrementAndRate:(BOOL)canPromptForRating {
[self incrementUseCount];
if (canPromptForRating &&
[self ratingConditionsHaveBeenMet] &&
[self connectedToNetwork])
{
dispatch_async(dispatch_get_main_queue(),
^{
[self showRatingAlert];
});
}
}
- (void)incrementSignificantEventAndRate:(BOOL)canPromptForRating {
[self incrementSignificantEventCount];
if (canPromptForRating &&
[self ratingConditionsHaveBeenMet] &&
[self connectedToNetwork])
{
dispatch_async(dispatch_get_main_queue(),
^{
[self showRatingAlert];
});
}
}
+ (void)appLaunched {
[Appirater appLaunched:YES];
}
+ (void)appLaunched:(BOOL)canPromptForRating {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
[[Appirater sharedInstance] incrementAndRate:canPromptForRating];
});
}
- (void)hideRatingAlert {
if (self.ratingAlert.visible) {
if (_debug)
NSLog(@"APPIRATER Hiding Alert");
[self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];
}
}
+ (void)appWillResignActive {
if (_debug)
NSLog(@"APPIRATER appWillResignActive");
[[Appirater sharedInstance] hideRatingAlert];
}
+ (void)appEnteredForeground:(BOOL)canPromptForRating {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
[[Appirater sharedInstance] incrementAndRate:canPromptForRating];
});
}
+ (void)userDidSignificantEvent:(BOOL)canPromptForRating {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
[[Appirater sharedInstance] incrementSignificantEventAndRate:canPromptForRating];
});
}
+ (id)getRootViewController {
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
if (window.windowLevel != UIWindowLevelNormal) {
NSArray *windows = [[UIApplication sharedApplication] windows];
for(window in windows) {
if (window.windowLevel == UIWindowLevelNormal) {
break;
}
}
}
for (UIView *subView in [window subviews])
{
UIResponder *responder = [subView nextResponder];
if([responder isKindOfClass:[UIViewController class]]) {
return responder;
}
}
return nil;
}
+ (void)rateApp {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
[userDefaults synchronize];
//Use the in-app StoreKit view if available (iOS 6) and imported. This works in the simulator.
if (NSStringFromClass([SKStoreProductViewController class]) != nil) {
SKStoreProductViewController *storeViewController = [[SKStoreProductViewController alloc] init];
NSNumber *appId = [NSNumber numberWithInteger:_appId.integerValue];
[storeViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier:appId} completionBlock:nil];
storeViewController.delegate = self.sharedInstance;
if ([self.sharedInstance.delegate respondsToSelector:@selector(appiraterWillPresentModalView:animated:)]) {
[self.sharedInstance.delegate appiraterWillPresentModalView:self.sharedInstance animated:_usesAnimation];
}
[[self getRootViewController] presentViewController:storeViewController animated:_usesAnimation completion:^{
[self setModalOpen:YES];
//Temporarily use a black status bar to match the StoreKit view.
[self setStatusBarStyle:[UIApplication sharedApplication].statusBarStyle];
[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:_usesAnimation];
}];
//Use the standard openUrl method if StoreKit is unavailable.
} else {
#if TARGET_IPHONE_SIMULATOR
NSLog(@"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page.");
#else
NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
#endif
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
switch (buttonIndex) {
case 0:
{
// they don't want to rate it
[userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];
[userDefaults synchronize];
if(self.delegate && [self.delegate respondsToSelector:@selector(appiraterDidDeclineToRate:)]){
[self.delegate appiraterDidDeclineToRate:self];
}
break;
}
case 1:
{
// they want to rate it
[Appirater rateApp];
if(self.delegate && [self.delegate respondsToSelector:@selector(appiraterDidOptToRate:)]){
[self.delegate appiraterDidOptToRate:self];
}
break;
}
case 2:
// remind them later
[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterReminderRequestDate];
[userDefaults synchronize];
if(self.delegate && [self.delegate respondsToSelector:@selector(appiraterDidOptToRemindLater:)]){
[self.delegate appiraterDidOptToRemindLater:self];
}
break;
default:
break;
}
}
//Delegate call from the StoreKit view.
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {
[Appirater closeModal];
}
//Close the in-app rating (StoreKit) view and restore the previous status bar style.
+ (void)closeModal {
if (_modalOpen) {
[[UIApplication sharedApplication]setStatusBarStyle:_statusBarStyle animated:_usesAnimation];
BOOL usedAnimation = _usesAnimation;
[self setModalOpen:NO];
[[UIApplication sharedApplication].keyWindow.rootViewController dismissViewControllerAnimated:_usesAnimation completion:^{
if ([self.sharedInstance.delegate respondsToSelector:@selector(appiraterDidDismissModalView:animated:)]) {
[self.sharedInstance.delegate appiraterDidDismissModalView:(Appirater *)self animated:usedAnimation];
}
}];
[self.class setStatusBarStyle:(UIStatusBarStyle)nil];
}
}
@end

View File

@ -0,0 +1,14 @@
Pod::Spec.new do |s|
s.name = 'Appirater'
s.version = '1.0.0'
s.platform = :ios
s.summary = "A utility that reminds your iPhone app's users to review the app."
s.homepage = 'http://arashpayan.com/blog/2009/09/07/presenting-appirater/'
s.author = { 'Arash Payan' => 'arash.payan@gmail.com' }
s.source = { :git => 'https://github.com/arashpayan/appirater.git', :commit => '1f6edfb85ec242be0321e5045331b475e0720043' }
s.source_files = '*.{h,m}'
s.resources = '*.lproj'
s.frameworks = 'CFNetwork', 'SystemConfiguration'
s.weak_framework = 'StoreKit'
s.license = { :type => 'MIT', :text => 'Copyright 2012. Arash Payan. This library is distributed under the terms of the MIT/X11.' }
end

View File

@ -0,0 +1,22 @@
//
// AppiraterDelegate.h
// Banana Stand
//
// Created by Robert Haining on 9/25/12.
// Copyright (c) 2012 News.me. All rights reserved.
//
#import <Foundation/Foundation.h>
@class Appirater;
@protocol AppiraterDelegate <NSObject>
@optional
-(void)appiraterDidDisplayAlert:(Appirater *)appirater;
-(void)appiraterDidDeclineToRate:(Appirater *)appirater;
-(void)appiraterDidOptToRate:(Appirater *)appirater;
-(void)appiraterDidOptToRemindLater:(Appirater *)appirater;
-(void)appiraterWillPresentModalView:(Appirater *)appirater animated:(BOOL)animated;
-(void)appiraterDidDismissModalView:(Appirater *)appirater animated:(BOOL)animated;
@end

59
appirater-master/README.md Executable file
View File

@ -0,0 +1,59 @@
Introduction
------------
Appirater is a class that you can drop into any iPhone app (iOS 4.0 or later) that will help remind your users
to review your app on the App Store. The code is released under the MIT/X11, so feel free to
modify and share your changes with the world. Read on below for how to get started. If you need any help using,
the library check out the [Appirater group] [appiratergroup].
Getting Started
---------------
1. Add the Appirater code into your project.
2. If your project doesn't use ARC, add the `-fobjc-arc` compiler flag to `Appirater.m` in your target's Build Phases » Compile Sources section.
3. Add the `CFNetwork`, `SystemConfiguration`, and `StoreKit` frameworks to your project. Be sure to **change Required to Optional** for StoreKit in your target's Build Phases » Link Binary with Libraries section.
4. Call `[Appirater setAppId:@"yourAppId"]` with the app id provided by Apple. A good place to do this is at the beginning of your app delegate's `application:didFinishLaunchingWithOptions:` method.
5. Call `[Appirater appLaunched:YES]` at the end of your app delegate's `application:didFinishLaunchingWithOptions:` method.
6. Call `[Appirater appEnteredForeground:YES]` in your app delegate's `applicationWillEnterForeground:` method.
7. (OPTIONAL) Call `[Appirater userDidSignificantEvent:YES]` when the user does something 'significant' in the app.
Configuration
-------------
Appirater provides class methods to configure its behavior. See [`Appirater.h`] [Appirater.h] for more information.
```objc
[Appirater setAppId:@"552035781"];
[Appirater setDaysUntilPrompt:1];
[Appirater setUsesUntilPrompt:10];
[Appirater setSignificantEventsUntilPrompt:-1];
[Appirater setTimeBeforeReminding:2];
[Appirater setDebug:YES];
```
Help and Support Group
----------------------
Requests for help, questions about usage, suggestions and other relevant topics should be posted at the [Appirater group] [appiratergroup]. As much as I'd like to help everyone who emails me, I can't respond to private emails, but I'll respond to posts on the group where others can benefit from the Q&As.
License
-------
Copyright 2012. [Arash Payan] [arash].
This library is distributed under the terms of the MIT/X11.
While not required, I greatly encourage and appreciate any improvements that you make
to this library be contributed back for the benefit of all who use Appirater.
Ports for other SDKs
--------------
A few people have ported Appirater to other SDKs. The ports are listed here in hopes that they may assist developers of those SDKs. I don't know how closesly (if at all) they track the Objective-C version of Appirater. If you need support for any of the libraries, please contact the maintainer of the port.
+ MonoTouch. [Github] [monotouchport]
+ Corona SDK. [Github] [coronasdkport]
+ Titanium SDK. [Github] [titaniumport]
[appiratergroup]: http://groups.google.com/group/appirater
[homepage]: http://arashpayan.com/blog/index.php/2009/09/07/presenting-appirater/
[arash]: http://arashpayan.com
[Appirater.h]: https://github.com/arashpayan/appirater/blob/master/Appirater.h
[monotouchport]: https://github.com/chebum/Appirater-for-MonoTouch
[coronasdkport]: https://github.com/aliasgar84/Appirater
[titaniumport]: https://github.com/mpociot/TiAppirater

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Si li agrada utilitzar %@, li importaria prendres un moment per a valorar-lo? No trigarà més dun minut. Gràcies por la seva col·laboració!";
"Rate %@" = "Valorar %@";
"No, Thanks" = "No, gràcies";
"Remind me later" = "Recordar-mho més tard";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Pokud se Vám aplikace %@ líbí, mohli byste ji prosím ohodnotit v App Store? Zabere to jen chvilku. Díky za Vaši podporu!";
"Rate %@" = "Ohodnotit %@";
"No, Thanks" = "Ne, díky";
"Remind me later" = "Možná později";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Hvis du synes om at bruge %@, vil du have noget imod at bruge et kort øjeblik på at bedømme det? Det tager kun et minut. Tak for din støtte!";
"Rate %@" = "Bedøm %@";
"No, Thanks" = "Nej tak";
"Remind me later" = "Påmind mig senere";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Sie nutzen %@ gerne? Dann nehmen Sie sich bitte für eine Bewertung einen Moment Zeit! Es dauert nicht länger als eine Minute. Vielen Dank!";
"Rate %@" = "Bewerte %@";
"No, Thanks" = "Nein, Danke";
"Remind me later" = "Später erinnern";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Αν σου αρέσει το %@, θα μπορούσες να αφιερώσεις μια στιγμή για να το βαθμολογήσεις; Η διαδικασία είναι πολύ σύντομη. Ευχαριστούμε για τη στήριξη!";
"Rate %@" = "Βαθμολόγηση του %@";
"No, Thanks" = "Όχι, ευχαριστώ";
"Remind me later" = "Υπενθύμιση αργότερα";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!";
"Rate %@" = "Rate %@";
"No, Thanks" = "No, Thanks";
"Remind me later" = "Remind me later";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Si le gusta utilizar %@, ¿le importaría valorarlo? No le llevará más de un minuto. ¡Gracias por su colaboración!";
"Rate %@" = "Valorar %@";
"No, Thanks" = "No, gracias";
"Remind me later" = "Recordar más tarde";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Jos käytät mielelläsi %@, voisitko käyttää hetken ja arvostella sen? Se ei kestä minuuttia kauempaa. Kiitos tuestasi!";
"Rate %@" = "Arvioi %@";
"No, Thanks" = "Ei kiitos";
"Remind me later" = "Muistuta minua myöhemmin";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Si vous aimez %@, voulez-vous prendre un moment pour l'évaluer? Cela ne vous prendra pas plus d'une minute. Merci de votre soutien!";
"Rate %@" = "Notez %@";
"No, Thanks" = "Non, Merci";
"Remind me later" = "Rappelez-moi plus tard";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "אם נהנת להשתמש ב %@, האם תסכים לדרג אותה? זה לא יקח יותר מדקה. תודה על התמיכה!";
"Rate %@" = "דרג את %@";
"No, Thanks" = "לא תודה";
"Remind me later" = "מאוחר יותר";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Ha tetszik a %@, ne felejtsd el értékelni az App Store-ban! Csak egy perc az egész. Köszönet a támogatásért!";
"Rate %@" = "%@ értékelése";
"No, Thanks" = "Most inkább nem";
"Remind me later" = "Emlékeztess később";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Se trovi utile %@, perchè non spendere qualche momento per dare una valutazione? Non richiederà più di un minuto. Grazie per il supporto!";
"Rate %@" = "Valuta %@";
"No, Thanks" = "No, grazie";
"Remind me later" = "Ricordamelo più tardi";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "楽しんでいただけたならば簡単なご意見をお願いします。%@を評価しますか?";
"Rate %@" = "%@の評価";
"No, Thanks" ="いいえ";
"Remind me later" = "後で見る";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "%@ 사용이 맘에 드셨나요? 잠시만 시간을 내서 평가를 부탁드리겠습니다. 감사합니다!";
"Rate %@" = "%@ 평가하기";
"No, Thanks" = "평가하지 않겠습니다";
"Remind me later" = "다음에 평가하겠습니다";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Hvis du liker å bruke %@, kan du ta deg et øyeblikk for å vurdere den? Det vil ikke ta mer enn ett minutt. Takk for din støtte!";
"Rate %@" = "Vurder %@";
"No, Thanks" = "Nei, takk du";
"Remind me later" = "Påminn meg senere";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Als het gebruik van %@ je bevalt, zou je dan een momentje de tijd willen nemen om het te beoordelen? Het duurt nog geen minuut. Bedankt voor je steun!";
"Rate %@" = "%@ beoordelen";
"No, Thanks" = "Nee, bedankt";
"Remind me later" = "Herinner me er later aan";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Jeżeli podoba Ci się korzystanie z %@, może zechciałbyś poświęcić chwilę czasu, aby ocenić aplikację? Nie zajmie Ci to więcej niż minutę. Dziękujemy za pomoc!";
"Rate %@" = "Oceń %@";
"No, Thanks" = "Nie, dziękuję";
"Remind me later" = "Przypomnij później";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Se você gosta de usar o %@, que tal avaliá-lo? Não levará mais de um minuto. Agradecemos o seu apoio!";
"Rate %@" = "Avaliar o %@";
"No, Thanks" = "Não, obrigado";
"Remind me later" = "Mais tarde";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Если Вам понравилась %@, пожалуйста поставьте свою оценку. Это займет у Вас не более одной минуты.\n Спасибо за поддержку!";
"Rate %@" = "Оценить %@";
"No, Thanks" = "Нет, спасибо";
"Remind me later" = "Напомнить позже";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Pokiaľ sa Vám páči aplikácia %@, mohli by ste ju prosím ohodnotiť v App Store? Zaberie to len chvíľu. Vďaka za Vašu podporu!";
"Rate %@" = "Ohodnotiť %@";
"No, Thanks" = "Nie, ďakujem";
"Remind me later" = "Pripomenúť neskôr";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Om du tycker att %@ är ett praktiskt verktyg, kan du tänka dig att betygsätta det åt oss? Det tar bara en minut. Tack för hjälpen!";
"Rate %@" = "Betygsätt %@";
"No, Thanks" = "Nej tack";
"Remind me later" = "Påminn mig senare";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Eğer %@ uygulamasını kullanmaktan keyif alıyorsanız, onu değerlendirmek için zaman ayırabilir misiniz? Desteğiniz için teşekkür ederiz!";
"Rate %@" = "%@ uygulamasını değerlendir";
"No, Thanks" = "Hayır, teşekkürler";
"Remind me later" = "Daha sonra hatırlat";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "如果你喜欢使用%@,你介意花一点时间给它评分吗?不会超过一分钟。感谢您的支持!";
"Rate %@" = "给%@评分";
"No, Thanks" = "不,谢谢";
"Remind me later" = "稍后提醒我";

View File

@ -0,0 +1,4 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "如果你喜歡使用%@,你介意花一點時間給它評分嗎?不會超過一分鐘。感謝您的支持!";
"Rate %@" = "給%@評分";
"No, Thanks" = "不,謝謝";
"Remind me later" = "稍後提醒我";