Change iOS 10 notification image thumbnail size - swift

I'm new to Xcode and Swift. I'm tying to send a local notification with an image shown. I use UNNotificationAttachment to attach an image from the following code:
let content = UNMutableNotificationContent()
content.title = "Testing"
content.body = "Testing rich notification"
let attachement = try! UNNotificationAttachment(identifier: "image", url: Bundle.main.url(forResource: "myImg", withExtension: "png")!, options: nil)
content.attachments = [attachement]
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)
let request = UNNotificationRequest(identifier: "TenSecond", content: content, trigger: trigger) // Schedule the notification.
let center = UNUserNotificationCenter.current()
center.add(request) { (error : Error?) in
if error != nil {}
}
I can see a thumbnail on the right side of the notification banner, but it's too small. I want to increase the size of the thumbnail so the notification look like this:
Notification With larger thumbnail
Is it possible?

No, it's not possible, iOS determines the max size.

With iOS 10 you could use the UserNotificationsUI framework to replace the notification body with one that has a larger UIImageView for the thumbnail.
See Customizing the Appearance of Notifications for details.

Related

Is it possible to share story to instagram and copy text simultaneously (iOS, swift)

I tried to do like this, but it does not work, the text is not copied
if let urlScheme = URL(string: "instagram-stories://share") {
if UIApplication.shared.canOpenURL(urlScheme) {
let imageData: Data = UIImage(systemName:"pencil.circle.fill")!.pngData()!
let items:[String: Any] = ["public.utf8-plain-text": "text","com.instagram.sharedSticker.backgroundImage": imageData]
UIPasteboard.general.setItems([items])
UIApplication.shared.open(urlScheme, options: [:], completionHandler: nil)
}}
I would really appreciate any advice
2 things I can think of:
First, I am not sure the below data in your array can be properly handled by pastebin
let items:[String: Any] = ["public.utf8-plain-text": "text","com.instagram.sharedSticker.backgroundImage": imageData]
Next it seems that the activity of sharing causes data in the PasteBoard to be lost so I can offer the solution to put valid data into the PasteBoard (I am using string for example, you can use something else" from the completion handler of your sharing action, something like this might solve it:
UIApplication.shared.open(urlScheme, options: [:]) { (_) in
UIPasteboard.general.string =
"click on the screen until the paste button appears: https://google.com"
}
EDIT
It seems your set up was right and on reading the docs, IG stories should handle the Paste automatically as it seems to check the pasteboard when you execute this url scheme: instagram-stories://share - so it seems IG checks the pasteboard and performs a paste programmatically and that is why the pasteboard gets cleared.
Maybe because the image you choose is black on the black instagram background, it seems nothing is shared but with some proper image the result seems fine.
The other thing I noticed after reading their docs, they do not allow you to set captions anymore, I cannot find this key anymore public.utf8-plain-text
Another idea I can offer to share text is to convert text into an image and add it as a sticker as the sticker layer comes on top of the background image layer.
You can find multiple ways to convert text to an image and it is not relevant to your solution, here is one way I used
So bringing the code together, I have this:
// Just an example to convert text to UIImage
// from https://stackoverflow.com/a/54991797/1619193
extension String {
/// Generates a `UIImage` instance from this string using a specified
/// attributes and size.
///
/// - Parameters:
/// - attributes: to draw this string with. Default is `nil`.
/// - size: of the image to return.
/// - Returns: a `UIImage` instance from this string using a specified
/// attributes and size, or `nil` if the operation fails.
func image(withAttributes attributes: [NSAttributedString.Key: Any]? = nil, size: CGSize? = nil) -> UIImage? {
let size = size ?? (self as NSString).size(withAttributes: attributes)
return UIGraphicsImageRenderer(size: size).image { _ in
(self as NSString).draw(in: CGRect(origin: .zero, size: size),
withAttributes: attributes)
}
}
}
// Then inside some function of yours
func someFunction() {
if let urlScheme = URL(string: "instagram-stories://share") {
if UIApplication.shared.canOpenURL(urlScheme) {
let imageData: Data = UIImage(named: "bg")!.pngData()!
let textImage: Data = "Shawn Test".image(withAttributes: [.foregroundColor: UIColor.red,
.font: UIFont.systemFont(ofSize: 30.0)],
size: CGSize(width: 300.0, height: 80.0))!.pngData()!
let items = ["com.instagram.sharedSticker.stickerImage": textImage,
"com.instagram.sharedSticker.backgroundImage": imageData]
UIPasteboard.general.setItems([items])
UIApplication.shared.open(urlScheme, options: [:], completionHandler: nil)
}
}
}
I then see this in IG stories with correct background and text as sticker which can be moved.
Only downside of using the sticker is you cannot edit the text in Instagram.
Regarding the research looks like the only one workaround to have a text/link copied in the Pasteboard when IG Story is opened is to use:
UIPasteboard.general.string = "your link here"
but you need to do it with a delay - like:
UIApplication.shared.open(instagramStoryURL, options: [:]) { success in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
UIPasteboard.general.string = "your link here"
}
}
to try to be sure the it won't override:
UIPasteboard.general.items
that contains, for example, "com.instagram.sharedSticker.stickerImage"
Also, please be careful with a delay - as iOS has some privacy restrictions to allow copy data to UIPasteboard when the App is in background (based on the tests we have less than 1 second to do that.
It means that you could try to copy the link this way:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)
}
#objc func appMovedToBackground() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
UIPasteboard.general.string = "your link here"
}
}
Anyway, there is one obvious inconvenience.
Each time you try to call "instagram-stories://share" API the first time - you face a system popup that asks for the permisson to allow to open Instagram and also to allow paste the data.
In this case we'll lose, for example, "com.instagram.sharedSticker.stickerImage" data as by the delay it will be overrided by UIPasteboard.general.string.
But we could to make it expected for users by any UI/UX solution with instructions/guide.

Asynchronous loading image with request

I have an api in which I get a link for request. In order to get a picture, I need to make a request in response to which I receive image data. How can I make getting asynchronous images? I find a lot of libraries and videos in youtube where this make with image link. But how i can do it in my case?
let token_type = KeychainWrapper.standard.string(forKey: "token_type")
let access_token = KeychainWrapper.standard.string(forKey: "access_token")
let headers:HTTPHeaders? = ["Authorization": "\(token_type ?? "") \(access_token ?? "")"]
Alamofire.request(cellInfo.imageLink ?? "", method: .get, headers: headers).responseImage { response in
if let image = response.result.value {
cell.firstTypeImageView.image = image
}
}
The issue with your example is that if the cell is reused by the time the image is retrieved, you’ll be updating the wrong row with this image. If updating the image view, it’s better to use the UIImageView extension. You enjoy several benefits with table view cells when you do this because it will automatically cancel the prior request for this cell. This means that:
It eliminates the problem of scrolling quickly having the image view in a reused cell flickering as images are retrieved for rows in the table.
It also means that you don’t have to worry about the current cell getting backlogged behind requests for cells that are no longer visible.
So, you might do something like:
if let imageLink = cellInfo.imageLink, let url = URL(string: imageLink) {
var request = URLRequest(url: url)
let authValue = "\(token_type ?? "") \(access_token ?? "")"
request.setValue(authValue, forHTTPHeaderField: "Authorization")
cell.firstTypeImageView.af_setImage(withURLRequest: request)
}
Or maybe you have a placeholder image, e.g. blank.png, then you’d do:
cell.firstTypeImageView.af_setImage(withURLRequest: request, placeholderImage: UIImage(named: "blank"))
Note, if your images are much larger than the image view in which you’re presenting them, you can see some stuttering in the tableview as the OS struggles to deal with such large assets. In that scenario, you can add a resizing filter:
let filter = AspectScaledToFillSizeFilter(size: cell.firstTypeImageView.frame.size) // or use whatever size appropriate
cell.firstTypeImageView.af_setImage(withURLRequest: request, placeholderImage: UIImage(named: "blank"), filter: filter)

ios swift FBSDKShareKit Publish (Share) content without ShareDialog view controller

i want to put function with "sharing facebook" when "user start live"
if that Fb Button is on then user touches that Live Button,
the content will publish on user's timeline on facebook automatically, then start "Live Broadcasting"
so the ShareDialog will not be present up.
but if ShareDialog should be presented for permission,
i want to do it when user touches that fb button.
======== ref
https://developers.facebook.com/docs/sharing/opengraph/ios
var content = FBSDKShareLinkContent()
content.contentURL = URL.init(string: "https://www~")
content.hashtag = FBSDKHashtag(string: "#ABCDE")
// content.contentTitle = self.broadcastingInfo.title ?? ""
// content.imageURL = self.broadcastingInfo.image
// var shareDialog = FBSDKShareDialog()
// shareDialog.shareContent = content
// shareDialog.mode = .native
// try shareDialog.show()
// do not want shareDialog
FBSDKShareAPI.share(with: content, delegate: self)
// error : The operation couldn’t be completed. (com.facebook.sdk.core error 8.)

How to send audio file with image and caption in iMessage app for iOS 10?

I am creating iMessage app and trying to send audio or video file to other user.
Video file works and looks fine but its not working as expected with audio file.
My current code is:
let destinationFilename = mp3FileNames[i]
let destinationURL = docDirectoryURL.appendingPathComponent(destinationFilename)
if let conversation = activeConversation {
let layout = MSMessageTemplateLayout()
layout.image = UIImage.init(named: "audio-x-generic-icon")
layout.mediaFileURL = destinationURL
layout.caption = selectedSongObj.name
let message = MSMessage()
message.layout = layout
message.url = URL(string: "emptyURL")
conversation.insert(message, completionHandler: nil)
return
}
Looks like layout.mediaFileURL = destinationURL is not adding any file into message.
And when I try to send file with above code.It looks like shown below:
It looks fine but there is no audio to play but if I try this way:
let destinationFilename = mp3FileNames[i]
let destinationURL = docDirectoryURL.appendingPathComponent(destinationFilename)
if let conversation = activeConversation {
conversation.insertAttachment(destinationURL!, withAlternateFilename: nil, completionHandler: nil)
return
}
And result with above code is:
I can play audio for that message because it's there. But problem with that message is I can not attach any image or caption with it.
How can I attach image and audio file into same message.
And if possible instead of image can I add GIF?
Any help would be much appreciated, Thank you.
Not necessary to use GIF, iMessage extensions supports also PNGand JPEG image formats. Recommended image size is 300x300 points at #3x scale.
If the MSMessageTemplateLayout's image property has a non-nil value then
mediaFileURL property is ignored. So you can't send an image and an audio file at the same time. Docs

Media Image Loading Indefinitely

I'm currently using JSQMessagesViewController for showing the image bubble and SDImageWeb to download the images and display it. The way I'm doing this is that someone would send a person a text message containing a url and the sender and receiver would both check for that and if it matches display and download an image from the url. It would show up as an image bubble rather than text message.
Expected behavior
When sending media images or receiving I should have the images eventually load (there's a loading animation on the images). After it loads, I should easily see it next time I go on without loading since it's cached.
Actual behavior
When receiving media images, sometimes it loads right away but sometimes if it tries to load it will load indefinitely. I know it is done downloading because if I trigger a reload of collection view either through messaging something or going back to main view and coming back to the same viewcontroller it will show up. If I close my app and restart it, the pictures I have finished downloading should show up instead it will show up as loading again for indefinitely. It only happens to the ones most recent, the old ones are all okay.
Steps to reproduce
Use SD image to download images for media bubbles
Send images possibly on a slower internet where it takes more than a few milliseconds to load
Fixes I tried
The way I did this was I would receive a message containing a url and I download it and return back a JSQMessage that contains a media bubble. I tried reloading the collectionview at that index or reloading entire collectionview with a completion block in SD web but it ends up with a endless loop.
I'm not sure if this is currently a fault of SDweb or JSQMessageController. I have tried using Kingfisher as an image caching and downloading with relatively the same results.
Code
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
let message = self.messages[indexPath.item]
if (message.body!.rangeOfString ("An image https://x.com/uploads/") != nil) {
let types: NSTextCheckingType = .Link
let detector = try? NSDataDetector(types: types.rawValue)
guard let detect = detector else {
let JSQTypeMessage = JSQMessage(senderId: message.from, senderDisplayName: message.from, date: message.date, text: message.body)
return JSQTypeMessage
}
let matches = detect.matchesInString(message.body!, options: .ReportCompletion, range: NSMakeRange(0, message.body!.characters.count))
var stringUrl:NSURL?
stringUrl = matches[0].URL!
let tempImageView = UIImageView(image: nil)
tempImageView.sd_setImageWithURL(stringUrl, completed: nil)
let photoImage = JSQPhotoMediaItem(image: tempImageView.image)
// This makes it so the bubble can be incoming rather than just all outgoing.
if !(message.from == self.senderId) {
photoImage.appliesMediaViewMaskAsOutgoing = false
}
let message = JSQMessage(senderId: message.from, displayName: self.senderDisplayName, media: photoImage)
return message
}
let JSQTypeMessage = JSQMessage(senderId: message.from, senderDisplayName: message.from, date: message.date, text: message.body)
return JSQTypeMessage
}
I think what you what to do is use the completion handler that is built into sdWebImage
tempImageView.sd_setImageWithURL(stringUrl, completed: {
//Set your image in here because you know that you have an image
// Then reload the cell
Self.tableView.reloadCellAtIndexPath(indexPath)
})