So I'm using NSClassFromString to check if the user has iOS 5 or iOS 6 installed to use Apple's new iOS 6 MKMapItem. This is the code:
- (void)openDirections:(id)sender {
Class mapClass = NSClassFromString(#"MKMapItem");
if (mapClass == nil) {
// iOS 5, do something here
}
else {
// iOS 6, open up maps with MKMapItem.
}
}
By the code above, when I run it on iOS 5.1 simulator or a iOS 5.1 device, the iOS 6 branch gets run. However, if I use
Class mapClass = NSClassFromString(#"PKPass");
which was also introduced in iOS 6, my code follows the appropriate iOS 5 or iOS 6 branch. Am I missing something? Thanks.
MKMapItem exists in prior versions of iOS because it was in development then, therefore the class existed. Instead, Apple recommends that you should use the following code also checking for a method they specifically added in iOS 6.0:
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
// Use class
}
Information from MKMapItem Class Reference
Related
I'm creating a workout app and I'm trying to implement the workoutRecovery logic but the handleActiveWorkoutRecovery function is never being called when an app crashes or is forced closed.
Are there any special circumstances that must be met so that the handleActiveWorkoutRecovery?
func handleActiveWorkoutRecovery() {
NSLog("log: handleActiveWorkoutRecovery");
self.healthInfo.recoverWorkout()
self.healthInfo.workoutRecovery = true
}
Moreover, in Content.swift I have the following code so that in case the login is not working I could see visual feedback that the handleActiveWorkoutRecovery function is being called:
#EnvironmentObject var healthInfo: HealthInfo
var body: some View {
VStack{
if(healthInfo.workoutRecovery){
Text("RECOVERY")
}else{
TestView()
}
}
}
When the app relaunches it never goes to The Text("RECOVERY") view.
Deployment target is 6.1 and I'm using an Apple Watch 4 running 6.1 beta 3
Ive also tested the native apple workout app and that seems to recover as it should
I'd like to show maps on iOS 6 by using MKMapItem but I'd also like to use Google Maps for older iOS versions.
When I test my solution on iOS 5.1 I have this error
dyld: Symbol not found: _MKLaunchOptionsDirectionsModeDriving
This is my code :
if Utils.older_than_ios6?
url = "http://maps.google.com/maps?saddr=#{#party.place.location[1]},#{#party.place.location[0]}&daddr=#{#party.place.location[1]},#{#party.place.location[0]}"
App::open_url(url)
else
address_dictionnary = ({kABPersonAddressStreetKey: #party.place.street, kABPersonAddressCityKey: #party.place.city,kABPersonAddressZIPKey: #party.place.postal_code})
place = MKPlacemark.alloc.initWithCoordinate(#coords, addressDictionary: address_dictionnary)
mapItem = MKMapItem.alloc.initWithPlacemark(place)
mapItem.name = "#{#party.name}"
options = ({
MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving
})
mapItem.openInMapsWithLaunchOptions(options)
end
This link shows that MKLaunchOptionsDirectionsModeDriving is available only on iOS6+.
And just to be sure, did you add MapKit to the list of frameworks in your Rakefile ?
I want to check whether the screen is locked with private api.
And I get some code from google:
#import <SpringBoard/SpringBoard.h>
#import <SpringBoard/SBAwayController.h>
Class clsAway = objc_allocateClassPair(clsAlert, "SBAwayController", 0);
objc_registerClassPair(clsAway);
Class clsAwayController = objc_getClass("SBAwayController");
SBAwayController * controller = [clsAwayController sharedAwayController];
if ([controller isLocked]){
NSLog(#"double check Home ,now YES Lock");
}
else{
NSLog(#"double check Home ,now NO Lock");
}
To make these code to work, I download the private headers from kennytm's github and import SpringBoard.h and SBAwayController.h
Compile ok and run it on my iPhone 4S, it seems that I can get a non-nil pointer with objc_getClass("SBAwayController");
But the program crashed at line:
SBAwayController * controller = [clsAwayController sharedAwayController];
with an error: '+[SBAwayController sharedAwayController]: unrecognized selector sent to class 0x1456c0'
Any other works do I need to make these code to work?
I know that the usage of private api can cause the rejection from Apple, but I just want to know how to make it work. Thanks for any suggestions!
SBAwayController WAS NOT REMOVED IN iOS 5. How can you expect to use a SpringBoard method from another process? SpringBoard is NOT a framework. It's an executable.
I believe SBAwayController was removed in the iOS 5. I checked SpringBoard and it has only reminiscences of this class.
Victor is wrong. The class is still present in iOS 6
cy# c = SBAwayController.sharedAwayController;
#"<SBAwayController: 0x1c510580> <SBActivationContext: 0x1c50be50> activate: deactivate: "
cy# printMethods(SBAwayController);
[{selector:#selector(hasEverBeenLocked),implementation:0x109c49},{selector:#selector(activateLostModeForRemoteLock:),implementation:0x116505},{selector:#selector(unlockWithSound:),implementation:0x110835},{selector:#selector(frontLocked:animate:automatically:),implementation:0x1120d5},{selector:#selector(cancelDimTimer),implementation:0x11291d},{selector:#selector(activeAwayPluginController),implementation:0x116885},{selector:#selector(shouldShowInCallUI),implementation:0x116111
...
i'm using Three20 in XCode but i copied a piece of code like this:
if (TTIsPad()) {
SplitCatalogController* controller =
(SplitCatalogController*)[[TTNavigator navigator] viewControllerForURL:#"tt://catalog"];
SplitCatalogController* controller =
(SplitCatalogController*)[[TTNavigator navigator] viewControllerForURL:#"tt://catalog"];
TTDASSERT([controller isKindOfClass:[SplitCatalogController class]]);
map = controller.rightNavigator.URLMap;
}
But i don't know what does the function TTIsPad do, please help me.
It is a convenience method that returns true if the current device is an iPad, and false otherwise.
The source can be found here. It first checks whether the device is running iOS 3.2 or greater. If not, it returns false (iPads shipped with 3.2) If it is greater than 3.2, it returns the result of (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) which is true only if the device is an iPad.
I'm noticing my iAd is causing a crash on iOS 3.2. I am weak linking in the build settings. It crashes in my createAdBanner method
NSString *contentSize;
if (&ADBannerContentSizeIdentifierPortrait != nil) {
contentSize = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? ADBannerContentSizeIdentifierPortrait : ADBannerContentSizeIdentifierLandscape;
}
else {
contentSize = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? ADBannerContentSizeIdentifier320x50 : ADBannerContentSizeIdentifier480x32;
}
Here is the error that comes up.
This GDB was configured as "x86_64-apple-darwin".sharedlibrary apply-load-rules all
Attaching to process 4681.
Assertion failed: (cls), function getName, file /SourceCache/objc4_Sim/objc4-427.1.1/runtime/objc-runtime-new.m, line 3939.
Assertion failed: (cls), function getName, file /SourceCache/objc4_Sim/objc4-427.1.1/runtime/objc-runtime-new.m, line 3939.
Current language: auto; currently objective-c
(gdb)
I thought you were able to run iAds on 3.2 if you weak linked. Any ideas or suggestions?
http://developer.apple.com/library/ios/#documentation/userexperience/Reference/ADBannerView_Ref/Reference/Reference.html
ADBannerView is available in 4.0 or later.
You won't be able to show ads in 3.2
Aside from weak-linking, you must check if the ad classes are available on the device. To do so, you can use the following to test for the existence of a class:
Class adClass = NSClassFromString(#"AdBannerView");
if(adClass){
//ads are available so optionally show them
}else{
// ads are not available
}
To check for a particular method, you would use this:
BOOL methodExists = [someObject respondsToSelector:#selector(selectorToTestName:)];
if(methodExists){
//Safe to call selector
}else{
//The selector doesn't exist in this version of iOS.
}
You could also just use the above statement, "inlining" the boolean check:
if([someObject respondsToSelector:#selector(selectorToTestName:)]){
//Safe to call selector
}else{
//The selector doesn't exist in this version of iOS.
}
ADBannerViewcan be used in 4.0 and above. See the apple documentation
use below link it is giving more clearly even to use in ios 3.0+ IAD Tutorial you have to import _weak_framework iAd in the linkingFlags wich is available in the targets.Once go through the link.