iOS 10 app crashes when trying to save image to photo library - swift

I'm trying to save an image to the photo library in Swift 3 (I'm working with Xcode 8).
ViewController Code:
func shareImage(image: UIImage) {
let items = [image]
var activityVC: UIActivityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
let excludeActivities: [UIActivityType] = [UIActivityType.airDrop,
UIActivityType.assignToContact,
UIActivityType.addToReadingList,
UIActivityType.copyToPasteboard]
activityVC.excludedActivityTypes = excludeActivities
self.present(activityVC, animated: true, completion: nil)
}
When I run the application, and click on the button to take the screenshot (converting it to image, ..., that's all working perfectly), the app asks for permission to access the photo library, I tap the "OK" button, and then the app crashes. The image is not saved in the photo library.
The only clue I get from Xcode is the following:
2016-09-28 11:24:27.216043 Ajax Kids[4143:1545362] [error] error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Media/PhotoData/Photos.sqlite?readonly_shm=1 options:{
NSPersistentStoreFileProtectionKey = NSFileProtectionCompleteUntilFirstUserAuthentication;
NSReadOnlyPersistentStoreOption = 1;
NSSQLitePersistWALOption = 1;
NSSQLitePragmasOption = {
"journal_mode" = WAL;
};
} ... returned error Error Domain=NSCocoaErrorDomain Code=256 "The file couldn’t be opened." UserInfo={reason=Failed to access file: 1} with userInfo dictionary {
reason = "Failed to access file: 1";
}
2016-09-28 11:24:27.216433 Ajax Kids[4143:1545362] [Migration] Unexpected error opening persistent store <private>, cannot attempt migration <private>)
2016-09-28 11:24:27.216568 Ajax Kids[4143:1545362] [Migration] Failed to open store <private>. Requires update via assetsd (256: <private>)
Does anyone have any idea how to fix this?
Thanks in advance!
UPDATE
Sharing the image on Social Media works fine, so the problem is specified to saving the image in the photo library.

Add new records in your new InfoPlist.strings file.
<key>NSPhotoLibraryAddUsageDescription</key>
<string>$(PRODUCT_NAME)</string>
UPD: iOS 11 key

On iOS 11, there is a new property called NSPhotoLibraryAddUsageDescription, similar to NSPhotoLibraryUsageDescription. See https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html

Try to force request permissions like this:
PHPhotoLibrary.requestAuthorization { status in
if status == .authorized {
//do things
}
}
do not forget import Photos. Hope this helps.

I found the culprit in my particular case. We are using Leanplum for analytics and push notifications. The Leanplum.syncResourcesAsync method was causing the opening of the photo library to crash. It took a couple of days to find as I wasn't aware Leanplum was doing anything to hook into a user's photo library... which in itself is concerning.
We weren't using the functionality this particular method brings, so were able to just remove the method call and the photo library stopped crashing.

Related

NSURLErrorDomain: -1003

I am getting an NSURLErrorDomain: -1003 while I am running my application in Xcode. I haven't seen this error on StackOverflow, any clue about this?
I am using Alamofire 4
func fetchAllPosts() {
Alamofire.request("http://www.somthing.com/wp-json/wp/v2/posts?categories_exclude=9").responseJSON
{ response in
if let data = response.data {
do {
let newPosts = try JSONDecoder().decode(Posts.self, from: data)
self.posts = newPosts.items
// Success
self.fetchAllPostsDidSucceed()
print("number of posts loaded: \(newPosts.items.count)")
}
[17655:2080758] [] nw_proxy_resolver_create_parsed_array PAC evaluation error: NSURLErrorDomain: -1003
-1003 is NSURLErrorCannotFindHost.
If you ever need to look up a NSURLError code in the future, press shift+command+o (the letter “oh”) in Xcode, search for NSURLError, unselect the “Swift” toggle in the upper right corner of the search box and choose/open NSURLError.h, and you’ll see all the codes that header file.
This particular error can be caused by any of a number of issues. For example, if this is a macOS app, you may want to go to your target settings, click on the “Capabilities” tag and make sure that “Outgoing Connections (Client)” is selected.

i need help in adding facebook share into my ios application

i am trying to add facebook share dialog into my ios application and i found the official page from facebook on how to do it, but i run into a problem about ContentProtocol. i dont know what that is. here is the link to the guidence that i use . it is pretty straight forward. basically just install the pod facebookshare, import it and add few line of code, but i got problem on 'myContent'
here is the code
import FacebookShare
let shareDialog = ShareDialog(content: myContent)
shareDialog.mode = .Native
shareDialog.failsOnInvalidData = true
shareDialog.completion = { result in
// Handle share results
}
try shareDialog.show()
here is the link
https://developers.facebook.com/docs/swift/sharing/share-dialog
what should i put in the myContent?
I guess next link is explained what you can use as content and how to use it
Content-types
(From documentation) Currently, the Facebook SDK for Swift can share 4 different kinds of content:
Links - Represented by the LinkShareContent object.
Photos - Represented by the PhotoShareContent object.
Videos - Represented by the VideoShareContent object.
Open Graph - Represented by the OpenGraphShareContent object.
you can use FBSDKShareLinkContent
let content : FBSDKShareLinkContent = FBSDKShareLinkContent()
content.contentURL = NSURL(string: "//URL")
content.contentTitle = "MyApp"
content.contentDescription = "//Desc"
content.imageURL = NSURL(string:"//Image URL")

TWTRComposer() Application crashes when I try to open Composer

I am having an issue with TWTRComposer. I installed TwitterKit using pods followed all other instructions i.e. updated info.Plist , AppDelegate and so on. I am using Swift. When I call the func that handles the code the app crashes here, sample code below. On the line where composer.show(from: self.navigationController!) the error message is Thread 1:EXC_BREAKPOINT(code=1, subcode=0x1024ff1ac) I have no clue what this means. Any explanation and help is appreciated.
let composer = TWTRComposer()
composer.setText("just setting up my Twitter Kit")
composer.setImage(UIImage(named: "twitterkit"))
// Called from a UIViewController
composer.show(from: self.navigationController!) { (result) in
if (result == .done) {
print("Successfully composed Tweet")
} else {
print("Cancelled composing")
}
}

Mail - Add Account screen from UIActivityController

I implemented a simple UIActivityViewController as below
let activityController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
activityController.completionWithItemsHandler = { activityType, completed, returnedItems, activityError in
if let error = activityError where !completed && activityType != nil {
// report the error
}
}
I thought the Add Account screen for Mail could be handled automatically by the UIActivityViewController instance if the user have no mail accounts, but not, it's not doing it.
The first thing I tried was to analyze the completion closure: the activityError instance is nil and the completed value is false. Great, I put this workaround (i want to open from my aap. "settings >> mail >> add account " (the add account page) is it possible.?) whenever this closure with those values is called. But it's called also when the user press Cancel on the mail composer.
So, how do Photos and other not-Apple apps they handle this scenario? Thanks
Seems like Apple doesn't handle well a NSURL type in the activityItems.
I solved it by using absoluteString value of that instance.

How to open settings app programmatically?

I'm using swift with ios 8.3. I want to open settings app from my application. I know that using the code
UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
will open my app settings. But I don't want to open my app settings. I just want to open the settings app and stay in the main page. If possible, navigate to "Cellular". Is there any way to acheive this?
Try this.
if let appSettings = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(appSettings, options: [:], completionHandler: nil)
}
Xcode 11.5 - iOS > 10
Update on 11-Oct-2016:
It won't work in iOS10 anymore. So far I haven't found any workaround. If you guys have any solution please let me know. thanks.
======================================
if the iOS version <= iOS9, you need set URL types:
You can do in this way:
let url:NSURL! = NSURL(string : "prefs:root=")
UIApplication.sharedApplication().openURL(url)
I have a demo on github: http://github.com/zhihuitang/SettingDemo.git
And you can find all available URLs as follows:
http://iphonedevwiki.net/index.php/Preferences.app
Preferences app registers a private URL scheme, prefs:, the list below details opening specific views 1[2]
prefs:root=General&path=About
prefs:root=General&path=ACCESSIBILITY
prefs:root=AIRPLANE_MODE
prefs:root=General&path=AUTOLOCK
prefs:root=General&path=USAGE/CELLULAR_USAGE
prefs:root=General&path=Bluetooth
prefs:root=General&path=DATE_AND_TIME
prefs:root=FACETIME
prefs:root=General
prefs:root=General&path=Keyboard
prefs:root=CASTLE
prefs:root=CASTLE&path=STORAGE_AND_BACKUP
prefs:root=General&path=INTERNATIONAL
prefs:root=LOCATION_SERVICES
prefs:root=ACCOUNT_SETTINGS
prefs:root=MUSIC
prefs:root=MUSIC&path=EQ
prefs:root=MUSIC&path=VolumeLimit
prefs:root=General&path=Network
prefs:root=NIKE_PLUS_IPOD
prefs:root=NOTES
prefs:root=NOTIFICATIONS_ID
prefs:root=Phone
prefs:root=Photos
prefs:root=General&path=ManagedConfigurationList
prefs:root=General&path=Reset
prefs:root=Sounds&path=Ringtone
prefs:root=Safari
prefs:root=General&path=Assistant
prefs:root=Sounds
prefs:root=General&path=SOFTWARE_UPDATE_LINK
prefs:root=STORE
prefs:root=TWITTER
prefs:root=General&path=USAGE
prefs:root=VIDEO
prefs:root=General&path=Network/VPN
prefs:root=Wallpaper
prefs:root=WIFI
prefs:root=INTERNET_TETHERING
hope this helpful to you.
YES, They made changes in iOS 10, Please change "prefs:" to "App-Prefs:"
guard let profileUrl = URL(string:"App-Prefs:root=General&path=ManagedConfigurationList") else {
return
}
if UIApplication.shared.canOpenURL(profileUrl) {
UIApplication.shared.open(profileUrl, completionHandler: { (success) in
print(" Profile Settings opened: \(success)")
})
}