iOS: Keep application running in background

2019-01-07 12:29发布

How do I keep my application running in the background? Would I have to jailbreak my iPhone to do this? I just need this app to check something from the internet every set interval and notify when needed, for my own use.

7条回答
劳资没心,怎么记你
2楼-- · 2019-01-07 12:29

I know this is not the answer to your question, but I think it is a solution.

This assumes that your trying to check something or get data from the internet on a regular basis?

Create a service that checks the internet every set interval for whatever it is you want to know, and create a push notification to alert you of it, if the server is down, or whatever it is your trying to monitor has changed state. Just an idea.

查看更多
放我归山
3楼-- · 2019-01-07 12:29

You can already do this in the applicationDidEnterBackground Method

查看更多
别忘想泡老子
4楼-- · 2019-01-07 12:34

I found a way, to keep app running in background by playing silence

Make sure, that you selected audio playback in background modes

Also, don't use this method for long time, since it consumes CPU resources and battery juice, but I think it's a suitable way to keep app alive for a few minutes.

Just create an instance of SilencePlayer, call play() and then stop(), when you done

import CoreAudio

public class SilencePlayer {
    private var audioQueue: AudioQueueRef? = nil
    public private(set) var isStarted = false

    public func play() {
        if isStarted { return }
        print("Playing silence")
        let avs = AVAudioSession.sharedInstance()
        try! avs.setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)
        try! avs.setActive(true)
        isStarted = true
        var streamFormat = AudioStreamBasicDescription(
            mSampleRate: 16000,
            mFormatID: kAudioFormatLinearPCM,
            mFormatFlags: kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked,
            mBytesPerPacket: 2,
            mFramesPerPacket: 1,
            mBytesPerFrame: 2,
            mChannelsPerFrame: 1,
            mBitsPerChannel: 16,
            mReserved: 0
        )
        let status = AudioQueueNewOutput(
            &streamFormat,
            SilenceQueueOutputCallback,
            nil, nil, nil, 0,
            &audioQueue
        )
        print("OSStatus for silence \(status)")
        var buffers = Array<AudioQueueBufferRef?>.init(repeating: nil, count: 3)
        for i in 0..<3 {
            buffers[i]?.pointee.mAudioDataByteSize = 320
            AudioQueueAllocateBuffer(audioQueue!, 320, &(buffers[i]))
            SilenceQueueOutputCallback(nil, audioQueue!, buffers[i]!)
        }
        let startStatus = AudioQueueStart(audioQueue!, nil)
        print("Start status for silence \(startStatus)")
    }

    public func stop() {
        guard isStarted else { return }
        print("Called stop silence")
        if let aq = audioQueue {
            AudioQueueStop(aq, true)
            audioQueue = nil
        }
        isStarted = false
    }

}

fileprivate func SilenceQueueOutputCallback(_ userData: UnsafeMutableRawPointer?, _ audioQueueRef: AudioQueueRef, _ bufferRef: AudioQueueBufferRef) -> Void {
    let pointer = bufferRef.pointee.mAudioData
    let length = bufferRef.pointee.mAudioDataByteSize
    memset(pointer, 0, Int(length))
    if AudioQueueEnqueueBuffer(audioQueueRef, bufferRef, 0, nil) != 0 {
        AudioQueueFreeBuffer(audioQueueRef, bufferRef)
    }
}

Tested on iOS 10 and Swift 4

查看更多
Animai°情兽
5楼-- · 2019-01-07 12:46

Use local notifications to do that. But this will not check every time. You will have to set a time where you will check your specific event, you may shorten this by decreasing your time slot. Read more about local notification to know how to achieve this at:

http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction/Introduction.html

查看更多
手持菜刀,她持情操
6楼-- · 2019-01-07 12:50

Yes, no need to jailbreak. Check out the "Implementing long-running background tasks" section of this doc from Apple.

From Apple's doc: Declaring Your App’s Supported Background Tasks

Support for some types of background execution must be declared in advance by the app that uses them. An app declares support for a service using its Info.plist file. Add the UIBackgroundModes key to your Info.plist file and set its value to an array containing one or more of the following strings: (see Apple's doc from link mentioned above.)

查看更多
叼着烟拽天下
7楼-- · 2019-01-07 12:50

Yes you can do something like this. For that you need to set entry in info.plist to tell os that my app will run in background. I have done this while I wanted to pass user's location after particular time stamp to server. For that I have set "Required background modes" set to "App registers for location updates".

You can write a handler of type UIBackgroundTaskIdentifier.

查看更多
登录 后发表回答