Block syntax translation problems Objective C to Swift - ios

TWPhotoPickerController *photoPicker = [[TWPhotoPickerController alloc] init];
photoPicker.cropBlock = ^(UIImage *image) {
//do something
};
[self presentViewController:photoPicker animated:YES completion:NULL];
Been stuck on this for way too long. I have imported all the correct header files into my bridging header file... just need to know how do I translate this block into swift syntax?

It should be something like this:
var photoPicker = TWPhotoPickerController()
photoPicker.cropBlock = { (image: UIImage) -> () in
// do something
}
presentViewController(photoPicker, animated: true, completion: nil)

Related

How to use ALCameraViewController library in an Objective C project

The documents say to use this in swift:
let cameraViewController = CameraViewController { [weak self] image, asset in
// Do something with your image here.
self?.dismiss(animated: true, completion: nil)
}
present(cameraViewController, animated: true, completion: nil)
But I don't know how to convert this to Objective C.
It's just clever looking code because he's got Swift default values in the initializer for CameraViewController. Objective-C does not support default values, so you need to provide them. The source is right here.
Something like this:
croppingParameters: CroppingParameters = CroppingParameters(),
allowsLibraryAccess: Bool = true,
allowsSwapCameraOrientation: Bool = true,
allowVolumeButtonCapture: Bool = true,
completion: #escaping CameraViewCompletion
__weak typeof(self) weakSelf = self;
CameraViewController *cameraViewController = [[CameraViewController alloc]
initWithCroppingParameters:[CroppingParameters new]
allowsLibraryAccess: YES
allowsSwapCameraOrientation: YES
allowVolumeButtonCapture: YES
completion: ^(UIImage *image, PHAsset *asset) {
[weakSelf dismissViewControllerAnimated:YES completion:nil];
}];
[self presentViewController:cameraViewController animated:YES completion:nil];
But since the ALCamera project doesn't seem to care that much about Objective-C, there might not be full support for it.

IMGLYMainEditorViewController completion block issue

I successfully implemented imglyKit in my Objective-C code, this library is made in swift language. Now i am opening a IMGLYMainEditorViewController from my viewcontroller.
My problem is that when the image is edited and when i press the done button i did not get the edited image. I checked the code and show that they set the completion block when they open IMGLYMainEditorViewController.
This is the code which is written in the library.
let editorViewController = IMGLYMainEditorViewController()
editorViewController.highResolutionImage = image
if let cameraController = cameraController {
editorViewController.initialFilterType = cameraController.effectFilter.filterType
editorViewController.initialFilterIntensity = cameraController.effectFilter.inputIntensity
}
editorViewController.completionBlock = editorCompletionBlock
private func editorCompletionBlock(result: IMGLYEditorResult, image: UIImage?) {
if let image = image where result == .Done {
UIImageWriteToSavedPhotosAlbum(image, self, "image:didFinishSavingWithError:contextInfo:", nil)
}
dismissViewControllerAnimated(true, completion: nil)
}
I wrote this code in my controller.
IMGLYMainEditorViewController *temp view = [[IMGLYMainEditorViewController alloc]init];
view.highResolutionImage = self.image_view.image;
[self.navigationController pushViewController:view animated:YES];
I want to set a block method here when i open a IMGLYMainEditorViewControlle so that i am able to get that edited image.
I did lots of try but not able to do that because i did not have a much knowledge about the block and how to deal with that. so please help me because i stuck here.
Remove the space between "temp view" instance name,
This is how you provide a completion block to an object:
IMGLYMainEditorViewController *tempView = [[IMGLYMainEditorViewController alloc] init];
tempView.completionBlock = ^(IMGLYEditorResult result, UIImage *image){
view.highResolutionImage = image;
};
[self.navigationController pushViewController:view animated:YES];

Instagram icon not showing in UIActivityViewController

I have an application which uses UIActivityViewController to share a link with NSExtensionActivationSupportsWebURLWithMaxCount like so:
NSURL *shareUrl = [NSURL URLWithString:[[sarray valueForKey:#"url"] description]];
NSString* someText = #"";
NSArray* dataToShare = #[shareUrl,someText]; // ...or whatever pieces of data you want to share.
NSArray *appActivities = [NSArray arrayWithObjects:[[UIActivity alloc] init], nil];
UIActivityViewController* activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:appActivities];
activityViewController.excludedActivityTypes=#[UIActivityTypeAddToReadingList,UIActivityTypeAirDrop,UIActivityTypePrint,UIActivityTypeAssignToContact];
[self.navigationController presentViewController:activityViewController animated:YES completion:nil];
[activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
if (!completed) return;
}];
Except for Instagram, all options are coming up in the UIActivityViewController.
Can anyone help me discover where I am going wrong or is this by default?
By default iOS doesn't have support for instagram. U might need to use 3rd party libraries.
For iOS 6 and above, you can use this UIActivity to upload images to Instagram which has the same workflow using iOS hooks but simplifies development.
Try this library
DMActivityInstagram
Swift 4.0+
To get the instagram app to show in the icon list, you must share an UIImage object in your dataToShare array.
I ran into a problem where my shared items contained a URL and an UIImage, and when sharing to iMessages I only wanted the URL to be shared and not the UIImage.
To solve this I made the presenting UIViewController conform to UIActivityItemSource protocol like so:
extension PresentingViewController: UIActivityItemSource {
public func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
UIImage() // This allows instagram app to show as a choice
}
public func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
guard let items = self.items else { return nil } // items to present
switch activityType! {
case .message, .postToTwitter, .copyToPasteboard, .mail:
return items.first(where: { $0 is URL })
default: // this catches the case where IG is tapped
return items.first(where: { $0 is UIImage }) as? UIImage
}
}
}
and instead of passing in an array of Activity Items that contain the object you want to share, you pass in the PresentingViewController like so:
// set up activity view controller
activityVC = UIActivityViewController(
activityItems: [PresentingViewController.self],
applicationActivities: [instaGramActivity]
)
self.present(activityVC, animated: true, completion: nil)
Instagram option will not be available with only text. For displaying instagram option in activity controller, you need to pass url object with text, or only url object else you can pass only image to share items which will enable instagram option for you.

swift spritekit Facebook share button

Hey there my app is almost ready for release but i want to add a Facebook share button. The thing is i have no idea how the communication between the scene and the viewcontroler works. i did my research but only found code in obj-c like this one
- (void)lkFaceBookShare {
NSString *serviceType = SLServiceTypeFacebook;
if (![SLComposeViewController isAvailableForServiceType:serviceType])
{
[self showUnavailableAlertForServiceType:serviceType];
}
else
{
SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:serviceType];
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.5f);
[self.view drawViewHierarchyInRect:rect afterScreenUpdates:YES];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[composeViewController addImage:viewImage];
NSString *initalTextString = [NSString stringWithFormat:#"Let's join together in the form of underground catch word go along with me!! Link: https://itunes.apple.com/us/app/uoi-hinh-bat-chu-gioi-duoi/id907330926?ls=1&mt=8"];
[composeViewController setInitialText:initalTextString];
UIViewController *vc = self.view.window.rootViewController;
[vc presentViewController:composeViewController animated:YES completion:nil];
}
}
- (void)showUnavailableAlertForServiceType:(NSString *)serviceType
{
NSString *serviceName = #"";
if (serviceType == SLServiceTypeFacebook)
{
serviceName = #"Facebook";
}
else if (serviceType == SLServiceTypeSinaWeibo)
{
serviceName = #"Sina Weibo";
}
else if (serviceType == SLServiceTypeTwitter)
{
serviceName = #"Twitter";
}
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Account"
message:[NSString stringWithFormat:#"Please go to the device settings and add a %# account in order to share through that service", serviceName]
delegate:nil
cancelButtonTitle:#"Dismiss"
otherButtonTitles:nil];
[alertView show];
}
my experience and knowledge is too low to port this too swift so i need some help with this D:
Thanks
This is some code I did for twitter a while ago which still works in swift. I show you how to convert it to Facebook below. Put this your viewController:
func showTweetSheet() {
let tweetSheet = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
tweetSheet.completionHandler = {
result in
switch result {
case SLComposeViewControllerResult.Cancelled:
//Add code to deal with it being cancelled
break
case SLComposeViewControllerResult.Done:
//Add code here to deal with it being completed
//Remember that dimissing the view is done for you, and sending the tweet to social media is automatic too. You could use this to give in game rewards?
break
}
}
tweetSheet.setInitialText("Test Twitter") //The default text in the tweet
tweetSheet.addImage(UIImage(named: "TestImage.png")) //Add an image if you like?
tweetSheet.addURL(NSURL(string: "http://twitter.com")) //A url which takes you into safari if tapped on
self.presentViewController(tweetSheet, animated: false, completion: {
//Optional completion statement
})
}
To convert it to Facebook, simply swap SLServiceTypeTwitter to SLServiceTypeFacebook and rename the variables for readability. If you want to call this method from the SKScene, you have to somehow alert the viewController that you want it to call a method.
My preferred way is to use NSNotificationCenter so that I post an alert from the scene and it is received by the viewController so that it fires a method. This is also incredibly easy to setup. In the scene, you need to put this line of code wherever you want to call the Facebook popup:
NSNotificationCenter.defaultCenter().postNotificationName("WhateverYouWantToCallTheNotification", object: nil)
This sends out a notification with a name. Now, in the viewController you need to subscribe to this alert by putting the following code in either viewDidLoad, viewDidAppear or something similar.
NSNotificationCenter.defaultCenter().addObserver(self, selector: "ThisIsTheMethodName", name: "WhateverYouCalledTheAlertInTheOtherLineOfCode", object: nil)
Now the scene will communicate with the viewController and you will be able to show the Facebook sheet. Remember to replace my strings with ones relative to your project. Hope this helps - sorry it was such a long answer!
func lkFaceBookShare() {
var serviceType: String = SLServiceTypeFacebook
if !SLComposeViewController.isAvailableForServiceType(serviceType) {
self.showUnavailableAlertForServiceType(serviceType)
}
else {
var composeViewController: SLComposeViewController = SLComposeViewController.composeViewControllerForServiceType(serviceType)
var keyWindow: UIWindow = UIApplication.sharedApplication().keyWindow
var rect: CGRect = keyWindow.bounds
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, false, 0.5)
self.view!.drawViewHierarchyInRect(rect, afterScreenUpdates: true)
var viewImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
composeViewController.addImage(viewImage)
var initalTextString: String = String(format: "Let's join together in the form of underground catch word go along with me!! Link: https://itunes.apple.com/us/app/uoi-hinh-bat-chu-gioi-duoi/id907330926?ls=1&mt=8")
composeViewController.initialText = initalTextString
var vc: UIViewController = self.view.window.rootViewController
vc.presentViewController(composeViewController, animated: true, completion: { _ in })
}
}
func showUnavailableAlertForServiceType(serviceType: String) {
var serviceName: String = ""
if serviceType == SLServiceTypeFacebook {
serviceName = "Facebook"
}
else if serviceType == SLServiceTypeSinaWeibo {
serviceName = "Sina Weibo"
}
else if serviceType == SLServiceTypeTwitter {
serviceName = "Twitter"
}
var alertView: UIAlertView = UIAlertView(title: "Account", message: "Please go to the device settings and add a \(serviceName) account in order to share through that service", delegate: nil, cancelButtonTitle: "Dismiss", otherButtonTitles: "")
alertView.show()
}
Swift Conversion of Obj-C answer posted by a very helpful user...... original post

open appstore as model view opens blank page ios

I am tring to open appstore page as model view inside application using following code
[NSDictionary dictionaryWithObject:#"APPID" forKey:SKStoreProductParameterITunesItemIdentifier];
SKStoreProductViewController *productViewController = [[SKStoreProductViewController alloc] init];
[self presentViewController:productViewController animated:YES completion:nil];
but when appstore is open inside application, it is opening as blank page.
Please refer screenshoot attached
I dont understand why appstore page of my app is not opening. I am passing APPID in above code.
Is there any other way to rate application without closing app ?
basically, something like this could help on you, after you linked the StoreKit.framework to your project. please note, it may not be working on simulator; on real device it works well.
.h
#interface UIYourViewController : UIViewController <SKStoreProductViewControllerDelegate> { }
.m
- (void)myOwnCustomMethod {
SKStoreProductViewController *_controller = [[SKStoreProductViewController alloc] init];
[_controller setDelegate:self];
[_controller loadProductWithParameters:[NSDictionary dictionaryWithObjectsAndKeys:#"364709193", SKStoreProductParameterITunesItemIdentifier, nil] completionBlock:^(BOOL result, NSError *error) {
if (result) {
[self.navigationController presentViewController:_controller animated:TRUE completion:nil];
} else {
// you can handle the error here, if you'd like to.
}
}];
}
#pragma mark - <SKStoreProductViewControllerDelegate>
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {
[self dismissViewControllerAnimated:TRUE completion:nil];
}
In Swift 3,
import StoreKit
class DetailViewController: UIViewController {
#IBAction func onEditButton(_ sender: UIBarButtonItem) {
let vc = SKStoreProductViewController()
vc.delegate = self
present(vc, animated: true, completion: nil)
vc.loadProduct(withParameters: [SKStoreProductParameterITunesItemIdentifier: 351091731]) { (success, error) in
if !success {
print("\(error)")
}
}
}
}
extension DetailViewController: SKStoreProductViewControllerDelegate {
func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
viewController.dismiss(animated: true, completion: nil)
}
}
Make sure SKStoreProductParameterITunesItemIdentifier's value is Number, as stated in its head file, though String value is currently OK.

Resources