MPNowPlayingInfoCenter : What is the best way to set MPMediaItemArtwork from an Url? - objective-c

All methods I found to set MPMediaItemArtwork of MPNowPlayingInfoCenter are with local images.
MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage: [UIImage imageNamed:#"myimage"];
But I need to set this from an imageURL
Currently i use this...
UIImage *artworkImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.currentTrack.imageUrl]]];
MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage: artworkImage];
[self.payingInfoCenter setValue:albumArt forKey:MPMediaItemPropertyArtwork];
Any idea?

That's my best solution:
- (void)updateControlCenterImage:(NSURL *)imageUrl
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSMutableDictionary *songInfo = [NSMutableDictionary dictionary];
UIImage *artworkImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
if(artworkImage)
{
MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage: artworkImage];
[songInfo setValue:albumArt forKey:MPMediaItemPropertyArtwork];
}
MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
infoCenter.nowPlayingInfo = songInfo;
});
}
/!\ if you've already setted the MPNowPlayingInfoCenter , get it or all other values will be overridden

let mpic = MPNowPlayingInfoCenter.default()
DispatchQueue.global().async {
if let urlString = yourUrlString, let url = URL(string:urlString) {
if let data = try? Data.init(contentsOf: url), let image = UIImage(data: data) {
let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { (_ size : CGSize) -> UIImage in
return image
})
DispatchQueue.main.async {
mpic.nowPlayingInfo = [
MPMediaItemPropertyTitle:"Title",
MPMediaItemPropertyArtist:"Artist",
MPMediaItemPropertyArtwork:artwork
]
}
}
}
}
That worked for me in iOS 11, swift 4

Here's a function that sets up a media session with image on the lock screen and control center:
(This code was a modified version of #NickDK's answer)
func setupNowPlaying(title: String, albumArtwork: String, artist:String, isExplicit: Bool, rate: Float, duration: Any) {
let url = URL.init(string: albumArtwork)!
let mpic = MPNowPlayingInfoCenter.default()
DispatchQueue.global().async {
if let data = try? Data.init(contentsOf: url), let image = UIImage(data: data) {
let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { (_ size : CGSize) -> UIImage in
return image
})
DispatchQueue.main.async {
mpic.nowPlayingInfo = [
MPMediaItemPropertyTitle: title,
MPMediaItemPropertyArtist: artist,
MPMediaItemPropertyArtwork:artwork,
MPMediaItemPropertyIsExplicit: isExplicit,
MPNowPlayingInfoPropertyPlaybackRate: soundManager.audioPlayer?.rate ?? 0,
MPMediaItemPropertyPlaybackDuration: CMTimeGetSeconds(soundManager.audioPlayer?.currentItem?.asset.duration ?? CMTime(seconds: 0, preferredTimescale: 0))
]
}
}
}
}
Usage:
setupNowPlaying(
title: "Pull up at the mansion",
albumArtwork: "https://static.wixstatic.com/media/89b4e7_5f29de0db68c4d888065b0f03d393050~mv2.png/v1/fill/w_512,h_512/ImageTitle.png",
artist: "DJ bon26",
isExplicit: true
)
Full usage:
import MediaPlayer
class SoundManager : ObservableObject {
var audioPlayer: AVPlayer?
func playSound(sound: String){
if let url = URL(string: sound) {
self.audioPlayer = AVPlayer(url: url)
}
}
}
struct ContentView: View {
#State var song1 = false
#StateObject private var soundManager = SoundManager()
var body: some View {
Image(systemName: song1 ? "pause.circle.fill": "play.circle.fill")
.font(.system(size: 25))
.padding(.trailing)
.onTapGesture {
playSound(
url: "https://static.wixstatic.com/mp3/0fd70b_8d4e15117ff0458792a6a901c6dddc6b.mp3",
title: "Pull up at the mansion",
albumArtwork: "https://static.wixstatic.com/media/89b4e7_5f29de0db68c4d888065b0f03d393050~mv2.png/v1/fill/w_512,h_512/ImageTitle.png",
artist: "DJ bon26",
isExplicit: true
)
}
}
func playSound(url: String, title: String, albumArtwork: String, artist: String, isExplicit: Bool) {
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options:
.init(rawValue: 0))
try AVAudioSession.sharedInstance().setActive(true)
soundManager.playSound(sound: url)
song1.toggle()
if song1{
soundManager.audioPlayer?.play()
setupNowPlaying(
title: title,
albumArtwork: albumArtwork,
artist: artist,
isExplicit: isExplicit
)
UIApplication.shared.beginReceivingRemoteControlEvents()
MPNowPlayingInfoCenter.default().playbackState = .playing
} else {
soundManager.audioPlayer?.pause()
}
}catch{
print("Something came up")
}
}
}
I believe this is very useful,
Brendan Okey-iwobi

Related

Swiftui how to use MKOverlayRenderer?

I want draw a route on the map.
but struct without using delegate.
struct MapView : UIViewRepresentable {
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
}
how can I do?
You need to specify a delegate if you want mapView(_:rendererFor:) to be called:
struct MapView: UIViewRepresentable {
#Binding var route: MKPolyline?
let mapViewDelegate = MapViewDelegate()
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ view: MKMapView, context: Context) {
view.delegate = mapViewDelegate // (1) This should be set in makeUIView, but it is getting reset to `nil`
view.translatesAutoresizingMaskIntoConstraints = false // (2) In the absence of this, we get constraints error on rotation; and again, it seems one should do this in makeUIView, but has to be here
addRoute(to: view)
}
}
private extension MapView {
func addRoute(to view: MKMapView) {
if !view.overlays.isEmpty {
view.removeOverlays(view.overlays)
}
guard let route = route else { return }
let mapRect = route.boundingMapRect
view.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10), animated: true)
view.addOverlay(route)
}
}
class MapViewDelegate: NSObject, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.fillColor = UIColor.red.withAlphaComponent(0.5)
renderer.strokeColor = UIColor.red.withAlphaComponent(0.8)
return renderer
}
}
Used like so:
struct ContentView : View {
#State var route: MKPolyline?
var body: some View {
MapView(route: $route)
.onAppear {
self.findCoffee()
}
}
}
private extension ContentView {
func findCoffee() {
let start = CLLocationCoordinate2D(latitude: 37.332693, longitude: -122.03071)
let region = MKCoordinateRegion(center: start, latitudinalMeters: 2000, longitudinalMeters: 2000)
let request = MKLocalSearch.Request()
request.naturalLanguageQuery = "coffee"
request.region = region
MKLocalSearch(request: request).start { response, error in
guard let destination = response?.mapItems.first else { return }
let request = MKDirections.Request()
request.source = MKMapItem(placemark: MKPlacemark(coordinate: start))
request.destination = destination
MKDirections(request: request).calculate { directionsResponse, _ in
self.route = directionsResponse?.routes.first?.polyline
}
}
}
}
Yielding:

Apple Maps Not Showing Map Overlay

I have a question regarding creating a Apple Map Overlay. I am trying to set on odd shape overlay from a JSON file. I have researched this on Stack Overflow, and have tried many of the solutions, but none seem to work. My code is below:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, UIGestureRecognizerDelegate {
#IBOutlet weak var mapView: MKMapView!
var coordinate: CLLocationCoordinate2D?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
mapView.showsUserLocation = true
mapView.delegate = self
mapView.mapType = .standard
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.TapGesture))
mapView.addGestureRecognizer(gestureRecognizer)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolygon {
let polygonView = MKPolygonRenderer(overlay: overlay)
polygonView.strokeColor = UIColor.black
polygonView.lineWidth = 0.5
polygonView.fillColor = UIColor.blue
return polygonView
}
return MKOverlayRenderer()
}
#objc func TapGesture(gesRect: UITapGestureRecognizer) {
let location = gesRect.location(in: mapView)
coordinate = mapView.convert(location,toCoordinateFrom: mapView)
let locCoord = mapView.convert(location, toCoordinateFrom: mapView)
print("Tapped at lat: \(locCoord.latitude) long: \(locCoord.longitude)")
print("Tapped at: \(location)")
self.retreiveShape() { (full_shape) in
if let shape = full_shape {
let polygon = MKPolygon.init(coordinates: shape, count: shape.count)
self.mapView.addOverlay(polygon)
} else {
print("ARRAY EMPTY")
}
}
}
func retreiveShape(completion: #escaping ([CLLocationCoordinate2D]?) -> ()) {
let path = Bundle.main.path(forResource: "shape", ofType: "json")
var coord_array = [CLLocationCoordinate2D]()
do {
let data = try Data.init(contentsOf: URL.init(fileURLWithPath: path!))
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
if let dictionary = json as? [String: Any] {
if let shape = dictionary["shape"] as? Array<Any> {
for regions in shape {
guard let region = regions as? Array<Array<Array<Double>>> else {
print("NOT HAPPENING")
return
}
for sections in region {
for coord in sections {
print("LATITUDE: \(coord[0])", "LONGITUDE: \(coord[1])")
let coordinatesToAppend = CLLocationCoordinate2D(latitude: coord[0], longitude: coord[1])
coord_array.append(coordinatesToAppend)
}
}
}
completion(coord_array)
}
}
} catch let error {
print(error)
}
}
The shape.json file is below:
{
"shape":[
[
[
[-81.621199, 30.282314],
[-81.613987, 30.281941],
[-81.611277, 30.284743],
[-81.602735, 30.284026],
[-81.601978, 30.292561],
[-81.596275, 30.290861],
[-81.592406, 30.290182],
[-81.571146, 30.28763],
[-81.55922, 30.286602],
[-81.559148, 30.291132],
[-81.558633, 30.294747],
[-81.55881, 30.312887],
[-81.558601, 30.312888],
[-81.558622, 30.316235],
[-81.558313, 30.316828],
[-81.552252, 30.320252],
[-81.548471, 30.321618],
[-81.527882, 30.323989],
[-81.529486, 30.328076],
[-81.537635, 30.336704],
[-81.537706, 30.337221],
[-81.538717, 30.338277],
[-81.539343, 30.338462],
[-81.542809, 30.341686],
[-81.547286, 30.345211],
[-81.552498, 30.348839],
[-81.552559, 30.352445],
[-81.577566, 30.352039],
[-81.578098, 30.353324],
[-81.578161, 30.35642],
[-81.577294, 30.3596],
[-81.576996, 30.366609],
[-81.58011, 30.366553],
[-81.580875, 30.37062],
[-81.580844, 30.373862],
[-81.581462, 30.374486],
[-81.578114, 30.374236],
[-81.572908, 30.374611],
[-81.562232, 30.372303],
[-81.551965, 30.366559],
[-81.548676, 30.365568],
[-81.540187, 30.378172],
[-81.538175, 30.380467],
[-81.538213, 30.387239],
[-81.536613, 30.388739],
[-81.512612, 30.392739],
[-81.505211, 30.390739],
[-81.490911, 30.392139],
[-81.49085, 30.389014],
[-81.489978, 30.389207],
[-81.488818, 30.38775],
[-81.489203, 30.389266],
[-81.487056, 30.390019],
[-81.481446, 30.391262],
[-81.479505, 30.39117],
[-81.477708, 30.390635],
[-81.476792, 30.390609],
[-81.476244, 30.391002],
[-81.473212, 30.389422],
[-81.472125, 30.388436],
[-81.472225, 30.388071],
[-81.474072, 30.386758],
[-81.475085, 30.384287],
[-81.474394, 30.381898],
[-81.473246, 30.38059],
[-81.473337, 30.380112],
[-81.47295, 30.379864],
[-81.472643, 30.380053],
[-81.471914, 30.379532],
[-81.471629, 30.378346],
[-81.470845, 30.377256],
[-81.468671, 30.376016],
[-81.466871, 30.374481],
[-81.465402, 30.374424],
[-81.464374, 30.373764],
[-81.465116, 30.373015],
[-81.467728, 30.372493],
[-81.469102, 30.371435],
[-81.470279, 30.369931],
[-81.472008, 30.370608],
[-81.473695, 30.370041],
[-81.471862, 30.370238],
[-81.470952, 30.369737],
[-81.471715, 30.369462],
[-81.470506, 30.369378],
[-81.469456, 30.368207],
[-81.468051, 30.367707],
[-81.46754, 30.366828],
[-81.466905, 30.366464],
[-81.467432, 30.366219],
[-81.466928, 30.365735],
[-81.465222, 30.365136],
[-81.464909, 30.364103],
[-81.46316, 30.362764],
[-81.463369, 30.36188],
[-81.462197, 30.361235],
[-81.461151, 30.36123],
[-81.46117, 30.360531],
[-81.461878, 30.360305],
[-81.461619, 30.359642],
[-81.461873, 30.358669],
[-81.461645, 30.358376],
[-81.460504, 30.358329],
[-81.46288, 30.357969],
[-81.462786, 30.357137],
[-81.461247, 30.355282],
[-81.460556, 30.352518],
[-81.46184, 30.340222],
[-81.462497, 30.339325],
[-81.465064, 30.337897],
[-81.471588, 30.328301],
[-81.472988, 30.318258],
[-81.469123, 30.319481],
[-81.450496, 30.320896],
[-81.443818, 30.302908],
[-81.442451, 30.301512],
[-81.438991, 30.299798],
[-81.437921, 30.298031],
[-81.437696, 30.284657],
[-81.438134, 30.283427],
[-81.439935, 30.281191],
[-81.440578, 30.279729],
[-81.440309, 30.276152],
[-81.441217, 30.271746],
[-81.440891, 30.270368],
[-81.440247, 30.269313],
[-81.438555, 30.267721],
[-81.43765, 30.266188],
[-81.43705, 30.257116],
[-81.441869, 30.256519],
[-81.45385, 30.252008],
[-81.466184, 30.251073],
[-81.472173, 30.251296],
[-81.491372, 30.251034],
[-81.507105, 30.253603],
[-81.510744, 30.253761],
[-81.530261, 30.250144],
[-81.56957, 30.249854],
[-81.584658, 30.251369],
[-81.586895, 30.251326],
[-81.589607, 30.250593],
[-81.593308, 30.248471],
[-81.605497, 30.260294],
[-81.621493, 30.282334],
[-81.621199, 30.282314]
]
]
]
}
It should create an odd shape overlay in the Southside of Jacksonville,FL, but it isn't. When the completion block is called the Coordinates are added to the array, but the map overlay isn't showing. Any thoughts?
Well this is somewhat embarrassing. I did as was suggested in the comments, and tried having the shape with nine vertices. It still didn't work. I then changed the coord from:
print("LATITUDE: \(coord[0])", "LONGITUDE: \(coord[1])")
let coordinatesToAppend = CLLocationCoordinate2D(latitude: coord[0], longitude: coord[1])
to:
print("LATITUDE: \(coord[1])", "LONGITUDE: \(coord[0])")
let coordinatesToAppend = CLLocationCoordinate2D(latitude: coord[1], longitude: coord[0])
It works perfectly. Turns out I had the Latitude and Longitude wrong.

How to add snooze effect once a notification is delivered in ios 10

I am implementing UserNotification in my app. When the notification gets fired it shows two action, in one i want to add snooze effect, it must snooze after 5 mins again. How to handle it ? thanks for all ! help if any one do have idea
Well to snooze notification you can create another notification with same details of current notification and increase the fire date by 5 mins.
Here is the code I used :
func snoozeScheduledNotification(notification:UILocalNotification) -> Void {
// Snooze for 10 mins
let localNotification = UILocalNotification()
localNotification.fireDate = notification.fireDate?.addingTimeInterval(60*10)
localNotification.repeatInterval = NSCalendar.Unit(rawValue: 0) // 0 = No Repeat
localNotification.alertBody = notification.alertBody
localNotification.soundName = notification.soundName
localNotification.userInfo = notification.userInfo
localNotification.category = notification.category
UIApplication.shared.scheduleLocalNotification(localNotification)
}
Hope it helps you.
The shortest and simplest code I found about it
For Swift 3/4
extension UNNotification {
func snoozeNotification(for hours: Int, minutes: Int, seconds: Int) {
let content = UNMutableNotificationContent()
content.title = "Another Alert"
content.body = "Your message"
content.sound = .default()
let identifier = self.request.identifier
guard let oldTrigger = self.request.trigger as? UNCalendarNotificationTrigger else {
debugPrint("Cannot reschedule notification without calendar trigger.")
return
}
var components = oldTrigger.dateComponents
components.hour = (components.hour ?? 0) + hours
components.minute = (components.minute ?? 0) + minutes
components.second = (components.second ?? 0) + seconds
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
debugPrint("Rescheduling failed", error.localizedDescription)
} else {
debugPrint("rescheduled success")
}
}
}
}
You just need to call it this way :
response.notification.snoozeNotification(for: 0, minutes: 0, seconds: 30)
Credit goes to Simon Ljungberg : https://gist.github.com/simme/96264d5ceee394083d18e2c64f42a3a9
For iOS10, use this code.
Use this code in AppDelegate.swift file.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
let center = UNUserNotificationCenter.current()
let category = UNNotificationCategory(identifier: "identifier", actions: [], intentIdentifiers: [])
center.setNotificationCategories([category])
center.requestAuthorization(options: [.badge, .alert , .sound]) { (greanted, error) in
print(error)
}
return true
}
You can put this code in any view controller.
let content = UNMutableNotificationContent.init()
content.title = "Notification Title"
content.subtitle = "Notification Sub-Title"
content.body = "Notification Body"
content.sound = UNNotificationSound.default()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: "identifier", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
UNUserNotificationCenter.current().delegate = self
if (error != nil){
//handle here
}
}
You can handle notification using following method:
extension UIViewController: UNUserNotificationCenterDelegate {
public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Swift.Void) {
completionHandler( [.alert, .badge, .sound])
}
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Swift.Void) {
print("Tapped in notification")
}
}
You can use this Blog as reference and Example.

AVMutableVideoComposition sometimes won't play video

I'm using this short snippet to set up my video. For some unknown reason - sometimes the video simply won't show up, while for other video it'll work perfectly.
let videoTrack: AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0]
let composition: AVMutableComposition = AVMutableComposition()
let videoComposition: AVMutableVideoComposition = AVMutableVideoComposition()
var videoSize: CGSize = videoTrack.naturalSize
let isPortrait_: Bool = self.isVideoPortrait(asset)
if isPortrait_ {
NSLog("video is portrait ")
videoSize = CGSizeMake(videoSize.height, videoSize.width)
}
composition.naturalSize = videoSize
videoComposition.renderSize = videoSize
// videoComposition.renderSize = videoTrack.naturalSize; //
videoComposition.frameDuration = CMTimeMake(1, 30)
let compositionVideoTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: 1)
let timeRange = videoTrack.timeRange
do {
try compositionVideoTrack.insertTimeRange(timeRange, ofTrack: videoTrack, atTime: kCMTimeZero)
} catch {
print("error")
}
let layerInst = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
layerInst.setTransform(videoTrack.preferredTransform, atTime: kCMTimeZero)
let inst: AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
inst.timeRange = timeRange
inst.layerInstructions = [layerInst]
videoComposition.instructions = [inst]
let playerItem = AVPlayerItem(asset: composition)
playerItem.videoComposition = videoComposition
Tho for some videos, it simply wont show them up.
Any suggestions? Thanks!!
Hello i had a relative similar code hope this helps you figure out your problem
class func MergeVideosSequentially(URLS : [NSURL], callback : (error : ErrorType? , outURL : NSURL?) -> Void){
let composition = AVMutableComposition()
//videoTrack
let videoTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
let audioTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
var cursorTime = kCMTimeZero
for URL in URLS {
let asset = AVAsset(URL: URL)
let assetVideoTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first! as AVAssetTrack
let assetAudioTrack = asset.tracksWithMediaType(AVMediaTypeAudio).first! as AVAssetTrack
var duration : CMTimeRange? = nil
duration = CMTimeRangeMake(kCMTimeZero, asset.duration)
do {
try videoTrack.insertTimeRange(duration!, ofTrack: assetVideoTrack, atTime: cursorTime)
try audioTrack.insertTimeRange(duration!, ofTrack: assetAudioTrack, atTime: cursorTime)
}catch {
print(error)
}
cursorTime = CMTimeAdd(cursorTime, asset.duration)
}
let directory = NSTemporaryDirectory()
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .LongStyle
dateFormatter.timeStyle = .ShortStyle
let date = dateFormatter.stringFromDate(NSDate())
let savePath = "\(directory)/mergedVideo-\(date).mp4"
let url = NSURL(fileURLWithPath: savePath)
let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
exporter!.outputURL = url
exporter!.shouldOptimizeForNetworkUse = true
exporter!.outputFileType = AVFileTypeMPEG4
exporter!.exportAsynchronouslyWithCompletionHandler({ () -> Void in
let outputURL = exporter!.outputURL
switch exporter!.status {
case .Completed :
dispatch_async(dispatch_get_main_queue(), { () -> Void in
callback(error: nil, outURL: outputURL)
})
default:
callback(error: CCMovieWriterError.CannotMergeClips, outURL: nil)
}
})
}

No Sim Card Installed Pop up showing twice in calling feature

I am using calling feature in App . Problem is that if no sim card installed in device then "No sim card installed" Alert view showing 2 times . I am using this code :
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:phoneNumber]])
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
}
Note: 1st Alert view automatically hide and again 2nd one is appearing .
Finally Found alternate solution for this :
Actually this is not an issue , This is transition effect :
To resolve it i have integrated below code before calling feature :
#import CoreTelephony;
CTTelephonyNetworkInfo *networkInfo = [CTTelephonyNetworkInfo new];
CTCarrier *carrier = [networkInfo subscriberCellularProvider];
if (!carrier.isoCountryCode) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"No SIM Card Installed" message:nil delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
else{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
}
import UIKit
import Alamofire
import NVActivityIndicatorView
import Reachability
//pod 'NVActivityIndicatorView'
//pod 'Alamofire', '~> 4.0'
//pod 'ReachabilitySwift'
typealias CompletionHandler = (_ success:Bool,_ reponsedata:Data) -> Void
typealias CompletionHandlerJson = (_ success:Bool,_ reponsedata:NSMutableDictionary) -> Void
typealias ResponseHandler = (_ success:Bool,_ data:NSData, _ error : String) -> Void
typealias ConnectivityHandler = (_ success:Bool) -> Void
class Connectivity {
class func internetConnection(completionHandler: #escaping ConnectivityHandler) {
//var Status:Bool = false
let url = NSURL(string: "http://google.com/")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "HEAD"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 1.0
let session = URLSession.shared
session.dataTask(with: request as URLRequest as URLRequest, completionHandler: {(data, response, error) in
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
completionHandler(true)
}
}
completionHandler(false)
}).resume()
}
class func connetivityAvailable() ->Bool {
return NetworkReachabilityManager()!.isReachable
}
}
class WebserviceHelper: NSObject {
class func postWebServiceCall(urlString:String, parameters:[String:AnyObject], encodingType: String, ShowProgress:Bool, completionHandler: #escaping CompletionHandler){
if Connectivity.connetivityAvailable() == false {
log(message: "internet is not available.")
HUD.hide()
AppDelegate.showMessage(message:NO_INTERNET_AVAILABLE)
completionHandler(false,Data())
return
}
if ShowProgress {
HUD.show(.systemActivity)
}
log(message: "\(urlString): + parametersnew")
let encoding: ParameterEncoding!
if encodingType == DefaultEncoding{
encoding = JSONEncoding.default
}else{
encoding = URLEncoding.httpBody
}
Alamofire.request(urlString, method: HTTPMethod.post, parameters: parameters, encoding: encoding , headers: HelperClass.sharedInstance.getApiHeader()).responseData(completionHandler: { (response) in
if response.result.isSuccess {
if ShowProgress {
HUD.hide()
}
if let result = response.result.value {
completionHandler(true,result)
}
}
if response.result.isFailure {
if ShowProgress{
HUD.hide()
}
print("Lost Connection %#",urlString)
if let responseCode = response.response?.statusCode as Int?{
print("Lost Connection with code %#",response.result.value as Any)
let responseDic = NSMutableDictionary()
responseDic.setObject(responseCode, forKey: "statusCode" as NSCopying)
completionHandler(false,Data())
}
completionHandler(false,Data())
}
})
}
class func postWebServiceJson(urlString:String, parameters:[String:AnyObject], encodingType: String, ShowProgress:Bool, completionHandler: #escaping CompletionHandlerJson){
if Connectivity.connetivityAvailable() == false {
AppDelegate.showMessage(message:NO_INTERNET_AVAILABLE)
completionHandler(false,NSMutableDictionary())
return
}
if ShowProgress {
HUD.show(.systemActivity)
}
log(message: "\(urlString): + parametersnew")
let encoding: ParameterEncoding!
if encodingType == DefaultEncoding{
encoding = JSONEncoding.default
}else{
encoding = URLEncoding.httpBody
}
Alamofire.request(urlString, method: HTTPMethod.post, parameters: parameters, encoding: encoding , headers: HelperClass.sharedInstance.getApiHeader()).responseJSON { (response) in
if response.result.isSuccess {
if ShowProgress {
HUD.hide()
}
if let result = response.result.value as? NSDictionary {
completionHandler(true,NSMutableDictionary(dictionary: result))
}
}
if response.result.isFailure {
if ShowProgress{
HUD.hide()
}
print("Lost Connection %#",urlString)
if let responseCode = response.response?.statusCode as Int?{
print("Lost Connection with code %#",response.result.value as Any)
let responseDic = NSMutableDictionary()
responseDic.setObject(responseCode, forKey: "statusCode" as NSCopying)
completionHandler(false,NSMutableDictionary())
}
completionHandler(false,NSMutableDictionary())
}
}
}
class func WebapiGetMethod(strurl:String, ShowProgress: Bool = false, completionHandler: #escaping CompletionHandlerJson){
if Connectivity.connetivityAvailable() == false {
log(message:"internet is not available.")
completionHandler(false,NSMutableDictionary())
//.. AppDelegate .showMessage(message:"Please check your internet connection")
return
}
if ShowProgress{
HUD.show(.systemActivity)
}
Alamofire.request(strurl).responseJSON { response in
if let status = response.response?.statusCode {
switch(status){
case 200:
if let result = response.result.value {
if let JSONdict = result as? NSMutableDictionary{
DispatchQueue.main.async {
completionHandler(true,JSONdict)
}
}
if ShowProgress {
HUD.hide()
}
}else{
if ShowProgress {
HUD.hide()
}
completionHandler(false,NSMutableDictionary())
}
log(message:"example success")
default:
log(message:"error with get response status: \(status)")
DispatchQueue.main.async {
if ShowProgress {
HUD.hide()
}
}
completionHandler(false,NSMutableDictionary())
}
}
DispatchQueue.main.async {
if ShowProgress {
HUD.hide()
}
}
}
}
class func getWebServiceCall(urlString:String,ShowProgress:Bool, completionHandler: #escaping CompletionHandler){
if Connectivity.connetivityAvailable() == false {
log(message: "internet is not available.")
HUD.hide()
AppDelegate.showMessage(message:NO_INTERNET_AVAILABLE)
completionHandler(false,Data())
return
}
if ShowProgress {
HUD.show(.systemActivity)
}
log(message: "\(urlString): + parametersnew")
Alamofire.request(urlString, method: .get, parameters: nil, encoding: URLEncoding.methodDependent, headers: HelperClass.sharedInstance.getApiHeader()).responseData { (response) in
if response.result.isSuccess {
if ShowProgress {
HUD.hide()
}
if let result = response.result.value {
completionHandler(true,result)
}
}
if response.result.isFailure {
if ShowProgress{
HUD.hide()
}
print("Lost Connection %#",urlString)
if let responseCode = response.response?.statusCode as Int?{
print("Lost Connection with code %#",response.result.value as Any)
let responseDic = NSMutableDictionary()
responseDic.setObject(responseCode, forKey: "statusCode" as NSCopying)
completionHandler(false,Data())
}
completionHandler(false,Data())
}
}
}
}