Using Facebook iOS SDK 3.7, Xcode 4.6, iOS simulator 6.0.
Here is my code:
NSLog (#"opening session");
[FBSession openActiveSessionWithPublishPermissions: #[#"publish_actions"]
defaultAudience: FBSessionDefaultAudienceFriends
allowLoginUI: YES
completionHandler: nil];
NSLog (#"open active session completed");
if ([FBSession activeSession].isOpen)
{
NSLog (#"initiating feed dialog");
[FBWebDialogs presentFeedDialogModallyWithSession: nil
parameters: nil
handler: nil];
}
When executed, it crashes with the following output to the debug console:
opening session
open active session completed
initiating feed dialog
-[FBDialog initWithURL:params:isViewInvisible:frictionlessSettings:delegate:]: unrecognized selector sent to instance 0xb93c7e0
I tried several variations, they all crash; the variation above is the simplest.
Thanks very much for any help.
The problem was that legacy code elsewhere in the system (an old version of the ShareKit library) was colliding with the Facebook SDK. When I removed the legacy code, then the code in the question above worked properly.
Related
One of my app's feature is detect keyDown event and do someting for some specific keys.
So, I use CGEventTapCreate to solve my problem and my code is like this:
if let tap = CGEventTapCreate(.CGHIDEventTap, .HeadInsertEventTap, .Default, CGEventMask(1 << CGEventType.KeyDown.rawValue), callBack, nil) {
let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode)
CGEventTapEnable(tap, true)
CFRunLoopRun()
}
Also, I deal with the process trust like:
let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as NSString: false]
let processTrusted = AXIsProcessTrustedWithOptions(options)
if processTrusted {
// do CGEventTapCreate()
} else {
// check again 1s later
performSelector("checkMethod", withObject: nil, afterDelay: 1)
}
It will be called per second until processTrusted is true.
Then strange thing happened:
When I run the app in Xcode and add trust Xcode in Privacy_Accessibility it all work fine. But When I run it with archive the app and Export as a Mac Application to my desktop, CGEventTapCreate() just not work.
After that I found this post Enable access for assistive devices programmatically on 10.9, it notice me that I need to relaunch the app after AXIsTrustedProcess().
You know, it's not a good idea to tell users to relaunch the app themselves. So I try to relaunch it programmatically and add these code into if processTrusted {}:
NSWorkspace.sharedWorkspace().launchApplication(NSProcessInfo.processInfo().processName)
NSApplication.sharedApplication().terminate(nil)
In other words, when I tick the app in Privacy_Accessibility, it will relaunch automatically.
Here comes another strange thing:
The app truly terminate and launch automatically. But when it finish relaunch, the app's Privacy_Accessibility is not tick.
It's really confuse me a lot, I hope someone will tell me the right way to deal with process trust and execute CGEventTapCreate() correctly.
Thanks!
Polling AXIsProcessTrusted and automatically relaunching is a nice touch. Users are often confused by this process, so anything that helps make it easier for them is good.
I'm pretty sure that an application that you launch inherits your current permissions, but don't have references handy to back that up. I have found that when debugging an application with CGEventTaps, I also have to give Xcode the Accessibility permissions that my app requests/requires.
But you can work around this by getting the system to launch your app for you. Try:
[NSTask launchedTaskWithLaunchPath:#"/bin/sh" arguments:[NSArray arrayWithObjects:#"-c", [NSString stringWithFormat:#"sleep 3 ; /usr/bin/open '%#'", [[NSBundle mainBundle] bundlePath]], nil]];
I would like to detect when a user refused the microphone permission on my iOS application.
I only get this value when I try to record the microphone: -120.000000 db
But before to get this I have to set up an AVAudioSession. Is there another function?
And I got this message in the output:
Microphone input permission refused - will record only silence
Thanks.
If you are still compiling with iOS SDK 6.0 (as I am) you have to be a bit more indirect than #Luis E. Prado, as the requestRecordPermission method doesn't exist.
Here's how I did it. Remove the autorelease bit if you're using ARC. On iOS6 nothing happens, and on iOS7 either the 'microphone is enabled' message is logged or the alert is popped up.
AVAudioSession *session = [AVAudioSession sharedInstance];
if ([session respondsToSelector:#selector(requestRecordPermission:)]) {
[session performSelector:#selector(requestRecordPermission:) withObject:^(BOOL granted) {
if (granted) {
// Microphone enabled code
NSLog(#"Microphone is enabled..");
}
else {
// Microphone disabled code
NSLog(#"Microphone is disabled..");
// We're in a background thread here, so jump to main thread to do UI work.
dispatch_async(dispatch_get_main_queue(), ^{
[[[[UIAlertView alloc] initWithTitle:#"Microphone Access Denied"
message:#"This app requires access to your device's Microphone.\n\nPlease enable Microphone access for this app in Settings / Privacy / Microphone"
delegate:nil
cancelButtonTitle:#"Dismiss"
otherButtonTitles:nil] autorelease] show];
});
}
}];
}
EDIT: It turns out that the withObject block is executed in a background thread, so DO NOT do any UI work in there, or your app may hang. I've adjusted the code above. A client pointed this out on what was thankfully a beta release. Apologies for the mistake.
Please note that this will only work if built with Xcode 5, and not with 4.6
Add the AVFoundation Framework to your project
Then import the AVAudioSession header file, from the AVFoundation framework, where you intend to check if the microphone setting is enabled
#import <AVFoundation/AVAudioSession.h>
Then simply call this method
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
if (granted) {
// Microphone enabled code
}
else {
// Microphone disabled code
}
}];
The first time this method runs, it will show the prompt to allow microphone access and based on the users response it will execute the completion block. From the second time onwards it will just act based on the stored setting on the device.
Swift answer:
if AVAudioSession.sharedInstance().recordPermission() == .Denied {
print("Microphone permission refused");
}
Or you can use framework like PermissionScope which permit to easily check permissions. https://github.com/nickoneill/PermissionScope
Edit: Swift 3 answer:
import AVFoundation
...
if AVAudioSession.sharedInstance().recordPermission() == .denied {
print("Microphone permission refused");
}
I'm not 100% certain if we're allowed to talk about iOS 7 outside of Apple's devforums, but I found the answer you're looking for there.
In short, you'll find your solution in the AVAudioSession.h header file in the SDK. And if you want to make use of it while still supporting iOS 6, make certain to use "respondsToSelector:" to check for the API availability.
I have added facebook sdk for accessing the user account. But when user is already login in facebook via iOS 6 facebook then in my app on the very first page it must shows the alert that app is asking for profile permissions. For it I have added following code in app delegate
[FBSession openActiveSessionWithAllowLoginUI:true];
NSArray *permissions = [NSArray arrayWithObjects:
#"friends_about_me",nil];
[FBSession openActiveSessionWithReadPermissions:permissions allowLoginUI:true
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (error) {
NSLog(#"Failure");
}
}];
return YES;
}
-(BOOL)application:(UIApplication *)application openURL:(NSURL )url
sourceApplication: (NSString) sourceApplication annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
I am getting the alert properly.
But when I click on OK button it gives me following error
FBSDKLog: System authorization failed:'The Facebook server could not fulfill this access request: remote_app_id does not match stored id '. This may be caused by a mismatch between the bundle identifier and your app configuration on the server at developers.facebook.com/apps.
But in my fb developer account , everything is fine. Please help me in resolving this issue.
Thanks!
Are you sure you have the same bundle ID set in your Facebook app settings? A good way to validate is to use this code to print the bundle ID to the console and compare it with your app settings on Facebook:
NSLog(#"Bundle ID: %#",[[NSBundle mainBundle] bundleIdentifier]);
Dear Sudha may be your bundle id is not confirmed yet from all server of facebook. You have to wait for it.
Beware that your bundle ID is case sensitive!
I Faced the same issue when i run my project in 3.5 inch simulator it shows the same error. It works fine in 4 inch simulator. I fixed this issue by going to my 3.5 inch simulator settings then i logged out from my Facebook account. then i re run the project it worked.
I am seeing that you can launch FaceTime from your app via
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"facetime://tel-number"]];
I am also reading that since there is no officially public FaceTime API apple will reject you.
Does anyone know if this rejection talk is true? PAIR has this feature and they have never been rejected.
This is now documented and legal:
https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/FacetimeLinks/FacetimeLinks.html#//apple_ref/doc/uid/TP40007899-CH2-SW1
My app got rejected for using FaceTime url. This is the part of response i got from Apple in resolution center.
We found the following non-public API/s in your app: Specifically,
your app uses the FaceTime URL scheme, which is undocumented.
If you have defined methods in your source code with the same names as
the above-mentioned APIs, we suggest altering your method names so
that they no longer collide with Apple's private APIs to avoid your
application being flagged in future submissions.
It was an update of a previous release. The first version got accepted without any problem. Now the update has been rejected due to the above mentioned reason. Seems i have to publish the app without the FaceTime thingy now.
Edit:
Its now legal to use FaceTime url in third party apps.
As a general rule, if you use undocumented API calls and apple catches you, they will reject your application. The reason is because they could change the API call that you are using in new IOS updates and thus would cause your application to crash or not work properly. You can try and submit using the undocumented API and hope that apple lets it through but as i said, you run the risk of Apple changing this api call or removing it completely from the OS in the future.
I don't see any reason this would be rejected, especially if there's already an app that uses this functionality. The App Store Review Guidelines are the best way to determine if your app will be rejected, and I don't see anything in there that applies to you situation.
Of course, Apple can do whatever they want, so the only way to be absolutely sure it will be accepted is to submit it, but I highly doubt you will have a problem.
It is official that you can use Native app URL strings for FaceTime video calls:
facetime:// 14085551234
facetime://user#example.com
Please refer to the link: https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/FacetimeLinks/FacetimeLinks.html
Though this feature is supported on all devices, you have to change the code a little bit for iOS 10.0 and above as openURL(_:) is deprecated.
https://developer.apple.com/documentation/uikit/uiapplication/1622961-openurl?language=objc
Please refer code below for the current and fallback mechanism, so this way it will not get rejected by Appstore.
-(void) callFaceTime : (NSString *) contactNumber
{
NSURL *URL = [NSURL URLWithString:[NSString
stringWithFormat:#"facetime://%#", contactNumber]];
if (#available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:URL options:#{}
completionHandler:^(BOOL success)
{
if (success)
{
NSLog(#"inside success");
}
else
{
NSLog(#"error");
}
}];
}
else {
// Fallback on earlier versions
NSString *faceTimeUrlScheme = [#"facetime://"
stringByAppendingString:contactNumber];
NSURL *facetimeURL = [NSURL URLWithString:faceTimeUrlScheme];
// Facetime is available or not
if ([[UIApplication sharedApplication] canOpenURL:facetimeURL])
{
[[UIApplication sharedApplication] openURL:facetimeURL];
}
else
{
// Facetime not available
NSLog(#"Facetime not available");
}
}
}
in contactNumber either pass phone number or appleid.
NSString *phoneNumber = #"9999999999";
NSString *appleId = #"abc#gmail.com";
[self callFaceTime:appleId];
objective-c ios
I am developing an application which uses both video recording and photo shoting.So i want to show buttons according to os for this i implement these methods.It's working fine when i build for OS 3.1 but when i build for OS 3.0 it shows errors
here are the methods
if ([self videoRecordingAvailable])
{
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.allowsImageEditing = YES;
imagePickerController.allowsEditing = YES;
imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
imagePickerController.videoMaximumDuration = 60.0f; // Length for video recording in seconds
imagePickerController.mediaTypes = [NSArray arrayWithObjects:#"public.movie", nil];
imagePickerController.showsCameraControls=YES;
[self.navigationController presentModalViewController:imagePickerController animated:YES];
}
- (BOOL) videoRecordingAvailable
{
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) return NO;
return [[UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera] containsObject:#"public.movie"];
}
the errors are
error: request for member 'allowsEditing' in something not a structure or union
error: request for member 'videoQuality' in something not a structure or union
error: 'UIImagePickerControllerQualityTypeHigh' undeclared (first use in this function)
(Each undeclared identifier is reported only once for each function it appears in.)
error: request for member 'videoMaximumDuration' in something not a structure or union
error: request for member 'showsCameraControls' in something not a structure or union
how do i solve this issue?
The problem is that the video capture has been added in 3.1, which means that the image picker from 3.0 does not support any of the video properties and methods (see the documentation and pay attention to the Availability sections).
As for the solution, I guess you could try using the message syntax instead of the dot syntax:
[picker setShowsCameraControls:YES];
This will give you warnings though (when compiled for 3.0 and older), and you have to be careful not to do it on older devices, because you’ll get an unknown selector exception. Or you can call the selector dynamically, which will get rid of the warnings and you can also check if the selector is supported first:
SEL msg = #selector(setShowsCameraControls:);
if ([picker respondsToSelector:msg])
[picker performSelector…];
There are already several questions about writing for different OS versions.
Responding to comments: I think the main problem is that you are blindly pasting the code without understading it. Don’t do that. Sit and think about what the code does, until you understand each and every line. Now to explain your problem more thoroughly:
The Image Picker in 3.0 has no video controls, since it can’t record video. Therefore when you try to compile a code such as picker.showsCameraControls, the compiler complains: There is no showsCameraControls property in the Image Picker class, that has only been added in 3.1.
But there is a way around that, you can use the message syntax ([foo setBar:…]) instead of the dot syntax (foo.bar=…). If the foo object has no setBar method, the compiler will warn you, but the code will compile. Now let’s use the message syntax to set the camera controls:
[picker setShowsCameraControls:YES];
When you compile this code for 3.1, it will compile without warning and run without error. When you compile for 3.0, you will get a warning from the compiler and if you run the code, it will fail (since there really is no showsCameraControls property). But that is not a problem, since you can only decide to run the fragile code if the OS supports it:
BOOL videoSupported = [picker respondsToSelector:#selector(setShowsCameraControls:)];
if (videoSupported) {
[picker setShowsCameraControls:YES];
// set all the other video properties
} else {
// do what makes sense without video support
}
This will work, but you’ll still get compiler warnings on 3.0. Now it depends on your default build target. If you build for 3.1, the warnings will disappear and the code should work on 3.0 just fine.