iPad version
This commit is contained in:
parent
eae41e0e3f
commit
797a47e84a
BIN
Default Espagram database DE.sqlite/StoreContent/persistentStore
Normal file
BIN
Default Espagram database DE.sqlite/StoreContent/persistentStore
Normal file
Binary file not shown.
BIN
Default Espagram database EN.sqlite/StoreContent/persistentStore
Normal file
BIN
Default Espagram database EN.sqlite/StoreContent/persistentStore
Normal file
Binary file not shown.
BIN
Default Espagram database NL.sqlite/StoreContent/persistentStore
Normal file
BIN
Default Espagram database NL.sqlite/StoreContent/persistentStore
Normal file
Binary file not shown.
@ -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;
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0450"
|
||||
LastUpgradeVersion = "0460"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@ -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>
|
||||
|
||||
12
Espagram/Espagram.entitlements
Normal file
12
Espagram/Espagram.entitlements
Normal 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>
|
||||
@ -15,6 +15,8 @@
|
||||
|
||||
- (void) cancelAddingWord;
|
||||
|
||||
- (NSString *) searchWordMeaning:(NSString *)word;
|
||||
|
||||
@end
|
||||
|
||||
@interface EspagramAddWordToLessonViewController : UIViewController
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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]];
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EspagramMainTableViewController : UITableViewController
|
||||
@interface EspagramMainTableViewController : UITableViewController <UISplitViewControllerDelegate>
|
||||
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIBarButtonItem *aboutButton;
|
||||
|
||||
@ -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]) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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
|
||||
|
||||
1329
Espagram/EspagramiPad.storyboard
Normal file
1329
Espagram/EspagramiPad.storyboard
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,4 +18,6 @@
|
||||
|
||||
- (NSString *) getTenseName;
|
||||
|
||||
- (NSString *) getLocalizedTense;
|
||||
|
||||
@end
|
||||
|
||||
@ -34,4 +34,9 @@
|
||||
return [tense getTenseInLanguage:self.conjugator];
|
||||
}
|
||||
|
||||
- (NSString *) getLocalizedTense;
|
||||
{
|
||||
return NSLocalizedString([@"TENSE_" stringByAppendingString:self.tense], nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -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]];
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
BIN
Espagram/de.lproj/Localizable.strings
Normal file
BIN
Espagram/de.lproj/Localizable.strings
Normal file
Binary file not shown.
@ -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"/>
|
||||
Binary file not shown.
Binary file not shown.
@ -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";
|
||||
|
||||
Binary file not shown.
2
appirater-master/.gitignore
vendored
Executable file
2
appirater-master/.gitignore
vendored
Executable file
@ -0,0 +1,2 @@
|
||||
|
||||
.DS_Store
|
||||
240
appirater-master/Appirater.h
Executable file
240
appirater-master/Appirater.h
Executable 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
492
appirater-master/Appirater.m
Executable 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
|
||||
14
appirater-master/Appirater.podspec
Executable file
14
appirater-master/Appirater.podspec
Executable 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
|
||||
22
appirater-master/AppiraterDelegate.h
Executable file
22
appirater-master/AppiraterDelegate.h
Executable 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
59
appirater-master/README.md
Executable 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
|
||||
4
appirater-master/ca.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/ca.lproj/AppiraterLocalizable.strings
Executable 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 prendre’s un moment per a valorar-lo? No trigarà més d’un minut. Gràcies por la seva col·laboració!";
|
||||
"Rate %@" = "Valorar %@";
|
||||
"No, Thanks" = "No, gràcies";
|
||||
"Remind me later" = "Recordar-m’ho més tard";
|
||||
4
appirater-master/cs.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/cs.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/da.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/da.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/de.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/de.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/el.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/el.lproj/AppiraterLocalizable.strings
Executable 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" = "Υπενθύμιση αργότερα";
|
||||
4
appirater-master/en.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/en.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/es.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/es.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/fi.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/fi.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/fr.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/fr.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/he.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/he.lproj/AppiraterLocalizable.strings
Executable 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" = "מאוחר יותר";
|
||||
4
appirater-master/hu.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/hu.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/it.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/it.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/ja.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/ja.lproj/AppiraterLocalizable.strings
Executable 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" = "後で見る";
|
||||
4
appirater-master/ko.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/ko.lproj/AppiraterLocalizable.strings
Executable 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" = "다음에 평가하겠습니다";
|
||||
4
appirater-master/nb.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/nb.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/nl.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/nl.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/pl.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/pl.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/pt.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/pt.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/ru.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/ru.lproj/AppiraterLocalizable.strings
Executable 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" = "Напомнить позже";
|
||||
4
appirater-master/sk.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/sk.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/sv.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/sv.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/tr.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/tr.lproj/AppiraterLocalizable.strings
Executable 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";
|
||||
4
appirater-master/zh-Hans.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/zh-Hans.lproj/AppiraterLocalizable.strings
Executable 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" = "稍后提醒我";
|
||||
4
appirater-master/zh-Hant.lproj/AppiraterLocalizable.strings
Executable file
4
appirater-master/zh-Hant.lproj/AppiraterLocalizable.strings
Executable 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" = "稍後提醒我";
|
||||
Loading…
x
Reference in New Issue
Block a user